Skytoby

深入理解Android Camera架构三-硬件抽象层

深入理解Android Camera架构三-硬件抽象层

一、概述

始于谷歌的Treble开源项目,基于接口与实现的分离的设计原则,谷歌加入了Camera Provider这一抽象层,该层作为一个独立进程存在于整个系统中,并且通过HIDL这一自定义语言成功地将Camera Hal Module从Camera Service中解耦出来,承担起了对Camera HAL的封装工作,纵观整个Android系统,对于Camera Provider而言,对上是通过HIDL接口负责与Camera Service的跨进程通信,对下通过标准的HAL3接口下发针对Camera的实际操作,这俨然是一个中央枢纽般的调配中心的角色,而事实上正是如此,由此看来,对Camera Provider的梳理变得尤为重要,接下来就以我个人理解出发来简单介绍下Camera Provider。

Camera Provider通过提供标准的HIDL接口给Camera Service进行调用,保持与Service的正常通信,其中谷歌将HIDL接口的定义直接暴露给平台厂商进行自定义实现,其中为了极大地减轻并降低开发者的工作量和开发难度,谷歌很好地封装了其跨进程实现细节,同样地,Camera Provider通过标准的HAL3接口,向下控制着具体的Camera HAL Module,而这个接口依然交由平台厂商负责去实现,而进程内部则通过简单的函数调用,将HIDL接口与HAL3接口完美的衔接起来,由此构成了Provider整体架构。

由图中可以看出Camera Provider进程由两部分组成,一是运行在系统中的主程序通过提供了标准的HIDL接口保持了与Camera Service的跨进程通讯,二是为了进一步扩展其功能,通过dlopen方式加载了一系列So库,而其中就包括了实现了Camera HAL3接口的So库,而HAL3接口主要定义了主要用于实现图像控制的功能,其实现主要交由平台厂商或者开发者来完成,所以Camera HAL3 So库的实现各式各样,在高通平台上,这里的实现是我们后面重点需要分析的CamX-CHI框架。在开始梳理CamX-CHI之前,不防先从上到下,以接口为主线简单梳理下Camera Provider的各个部分。

二、Camera HIDL接口

首先需要明确一个概念,就是HIDL是一种自定义语言,其核心是接口的定义,而谷歌为了使开发者将注意力落在接口的定义上而不是机制的实现上,主动封装了HIDL机制的实现细节,开发者只需要通过*.hal文件定义接口,填充接口内部实际的实现即可,接下来来看下具体定义的几个主要接口:(hardware\interfaces\camera\provider)

因为HIDL机制本身是跨进程通讯的,所以Camera Service本身通过HIDL接口获取的对象都会有Bn端和Bp端,分别代表了Binder两端,接下来为了方便理解,我们都省略掉Bn/Bp说法,直接用具体接口类代表,忽略跨进程两端的区别。

2.1 ICameraProvider.hal

ICameraProvider.hal源码如下:

[->hardware\interfaces\camera\provider\2.4\ICameraProvider.hal]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package android.hardware.camera.provider@2.4;

import ICameraProviderCallback;
import android.hardware.camera.common@1.0::types;
import android.hardware.camera.device@1.0::ICameraDevice;
import android.hardware.camera.device@3.2::ICameraDevice;

/**
* Camera provider HAL, which enumerates the available individual camera devices
* known to the provider, and provides updates about changes to device status,
* such as connection, disconnection, or torch mode enable/disable.
*
* The provider is responsible for generating a list of camera device service
* names that can then be opened via the hardware service manager.
*
* Multiple camera provider HALs may be present in a single system.
* For discovery, the service names, and process names, must be of the form
* "android.hardware.camera.provider@<major>.<minor>/<type>/<instance>"
* where
* - <major>/<minor> is the provider HAL HIDL version,
* - <type> is the type of devices this provider knows about, such as
* "internal", "legacy", "external", "remote" etc. The camera framework
* must not differentiate or chage its behavior based on the specific type.
* - <instance> is a non-negative integer starting from 0 to disambiguate
* between multiple HALs of the same type.
*
* The "legacy" type is only used for passthrough legacy HAL mode, and must
* not be used by a standalone binderized HAL.
*
* The device instance names enumerated by the provider in getCameraIdList() or
* ICameraProviderCallback::cameraDeviceStatusChange() must be of the form
* "device@<major>.<minor>/<type>/<id>" where
* <major>/<minor> is the HIDL version of the interface. <id> is either a small
* incrementing integer for "internal" device types, with 0 being the main
* back-facing camera and 1 being the main front-facing camera, if they exist.
* Or, for external devices, a unique serial number (if possible) that can be
* used to identify the device reliably when it is disconnected and reconnected.
*
* Multiple providers must not enumerate the same device ID.
*/
interface ICameraProvider {

/**
* setCallback:
*
* Provide a callback interface to the HAL provider to inform framework of
* asynchronous camera events. The framework must call this function once
* during camera service startup, before any other calls to the provider
* (note that in case the camera service restarts, this method must be
* invoked again during its startup).
*
* @param callback
* A non-null callback interface to invoke when camera events occur.
* @return status
* Status code for the operation, one of:
* OK:
* On success
* INTERNAL_ERROR:
* An unexpected internal error occurred while setting the callbacks
* ILLEGAL_ARGUMENT:
* The callback argument is invalid (for example, null).
*
*/
setCallback(ICameraProviderCallback callback) generates (Status status);

/**
* getVendorTags:
*
* Retrieve all vendor tags supported by devices discoverable through this
* provider. The tags are grouped into sections.
*
* @return status
* Status code for the operation, one of:
* OK:
* On success
* INTERNAL_ERROR:
* An unexpected internal error occurred while setting the callbacks
* @return sections
* The supported vendor tag sections; empty if there are no supported
* vendor tags, or status is not OK.
*
*/
getVendorTags() generates (Status status, vec<VendorTagSection> sections);

/**
* getCameraIdList:
*
* Returns the list of internal camera device interfaces known to this
* camera provider. These devices can then be accessed via the hardware
* service manager.
*
* External camera devices (camera facing EXTERNAL) must be reported through
* the device status change callback, not in this list. Only devices with
* facing BACK or FRONT must be listed here.
*
* @return status Status code for the operation, one of:
* OK:
* On a succesful generation of camera ID list
* INTERNAL_ERROR:
* A camera ID list cannot be created. This may be due to
* a failure to initialize the camera subsystem, for example.
* @return cameraDeviceServiceNames The vector of internal camera device
* names known to this provider.
*/
getCameraIdList()
generates (Status status, vec<string> cameraDeviceNames);

/**
* isSetTorchModeSupported:
*
* Returns if the camera devices known to this camera provider support
* setTorchMode API or not. If the provider does not support setTorchMode
* API, calling to setTorchMode will return METHOD_NOT_SUPPORTED.
*
* Note that not every camera device has a flash unit, so even this API
* returns true, setTorchMode call might still fail due to the camera device
* does not have a flash unit. In such case, the returned status will be
* OPERATION_NOT_SUPPORTED.
*
* @return status Status code for the operation, one of:
* OK:
* On a succesful call
* INTERNAL_ERROR:
* Torch API support cannot be queried. This may be due to
* a failure to initialize the camera subsystem, for example.
* @return support Whether the camera devices known to this provider
* supports setTorchMode API or not. Devices launched with SDK
* level 29 or higher must return true.
*
*/
isSetTorchModeSupported() generates (Status status, bool support);

/**
* getCameraDeviceInterface_VN_x:
*
* Return a android.hardware.camera.device@N.x/ICameraDevice interface for
* the requested device name. This does not power on the camera device, but
* simply acquires the interface for querying the device static information,
* or to additionally open the device for active use.
*
* A separate method is required for each major revision of the camera device
* HAL interface, since they are not compatible with each other.
*
* Valid device names for this provider can be obtained via either
* getCameraIdList(), or via availability callbacks from
* ICameraProviderCallback::cameraDeviceStatusChange().
*
* The returned interface must be of the highest defined minor version for
* the major version; it's the responsibility of the HAL client to ensure
* they do not use methods/etc that are not valid for the actual minor
* version of the device.
*
* @param cameraDeviceName the name of the device to get an interface to.
* @return status Status code for the operation, one of:
* OK:
* On a succesful generation of camera ID list
* ILLEGAL_ARGUMENT:
* This device name is unknown, or has been disconnected
* OPERATION_NOT_SUPPORTED:
* The specified device does not support this major version of the
* HAL interface.
* INTERNAL_ERROR:
* A camera interface cannot be returned due to an unexpected
* internal error.
* @return device The inteface to this camera device, or null in case of
* error.
*/
getCameraDeviceInterface_V1_x(string cameraDeviceName) generates
(Status status,
android.hardware.camera.device@1.0::ICameraDevice device);
getCameraDeviceInterface_V3_x(string cameraDeviceName) generates
(Status status,
android.hardware.camera.device@3.2::ICameraDevice device);

};

该文件中定义了ICameraProvider接口类,由CameraProvider继承并实现,在Camera Provider启动的时候被实例化,主要接口如下:

  • getCameraDeviceInterface_V3_x: 该方法主要用于Camera Service获取ICameraDevice,通过该对象可以控制Camera 设备的诸如配置数据流、下发request等具体行为。
  • setCallback: 将Camera Service 实现的ICameraProviderCallback传入Camera Provider,一旦Provider有事件产生时便可以通过该对象通知Camera Service。

2.2 ICameraProviderCallback.hal

ICameraProviderCallback.hal源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package android.hardware.camera.provider@2.4;

import android.hardware.camera.common@1.0::types;

/**
* Callback functions for a camera provider HAL to use to inform the camera
* service of changes to the camera subsystem.
*/
interface ICameraProviderCallback {

/**
* cameraDeviceStatusChange:
*
* Callback to the camera service to indicate that the state of a specific
* camera device has changed.
*
* On camera service startup, when ICameraProvider::setCallback is invoked,
* the camera service must assume that all internal camera devices are in
* the CAMERA_DEVICE_STATUS_PRESENT state.
*
* The provider must call this method to inform the camera service of any
* initially NOT_PRESENT devices, and of any external camera devices that
* are already present, as soon as the callbacks are available through
* setCallback.
*
* @param cameraDeviceServiceName The name of the camera device that has a
* new status.
* @param newStatus The new status that device is in.
*
*/
cameraDeviceStatusChange(string cameraDeviceName,
CameraDeviceStatus newStatus);

/**
* torchModeStatusChange:
*
* Callback to the camera service to indicate that the state of the torch
* mode of the flash unit associated with a specific camera device has
* changed. At provider registration time, the camera service must assume
* the torch modes are in the TORCH_MODE_STATUS_AVAILABLE_OFF state if
* android.flash.info.available is reported as true via the
* ICameraDevice::getCameraCharacteristics call.
*
* @param cameraDeviceServiceName The name of the camera device that has a
* new status.
* @param newStatus The new status that device is in.
*
*/
torchModeStatusChange(string cameraDeviceName,
TorchModeStatus newStatus);

};

该文件中定义了ICameraProviderCallback回调接口类,该接口由Camera Service 中的CameraProviderManager::ProviderInfo继承并实现,在Camera Service 启动的时候被实例化,通过调用ICameraProvider::setCallback接口注册到Camera Provider中,其主要接口如下:

  • cameraDeviceStatusChange: 将Camera 设备状态上传至Camera Service,状态由CameraDeviceStatus定义

2.3 ICameraDevice.ha

ICameraDevice.hal源码如下:

[->hardware\interfaces\camera\device\3.2\ICameraDevice.hal]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package android.hardware.camera.device@3.2;

import android.hardware.camera.common@1.0::types;
import ICameraDeviceSession;
import ICameraDeviceCallback;

/**
* Camera device HAL, first modern version
*
* Supports the android.hardware.Camera API, and the android.hardware.camera2
* API at LIMITED or better hardware level.
*
*/
interface ICameraDevice {

/**
* Get camera device resource cost information.
*
* @return status Status code for the operation, one of:
* OK:
* On success
* INTERNAL_ERROR:
* An unexpected internal camera HAL error occurred, and the
* resource cost is not available.
* CAMERA_DISCONNECTED:
* An external camera device has been disconnected, and is no longer
* available. This camera device interface is now stale, and a new
* instance must be acquired if the device is reconnected. All
* subsequent calls on this interface must return
* CAMERA_DISCONNECTED.
* @return resourceCost
* The resources required to open this camera device, or unspecified
* values if status is not OK.
*/
getResourceCost() generates (Status status, CameraResourceCost resourceCost);

/**
* getCameraCharacteristics:
*
* Return the static camera information for this camera device. This
* information may not change between consecutive calls.
*
* When an external camera is disconnected, its camera id becomes
* invalid. Calling this method with this invalid camera id must result in
* ILLEGAL_ARGUMENT; this may happen even before the device status callback
* is invoked by the HAL.
*
* @return status Status code for the operation, one of:
* OK:
* On a successful open of the camera device.
* INTERNAL_ERROR:
* The camera device cannot be opened due to an internal
* error.
* CAMERA_DISCONNECTED:
* An external camera device has been disconnected, and is no longer
* available. This camera device interface is now stale, and a new
* instance must be acquired if the device is reconnected. All
* subsequent calls on this interface must return
* CAMERA_DISCONNECTED.
*
* @return cameraCharacteristics
* The static metadata for this camera device, or an empty metadata
* structure if status is not OK.
*
*/
getCameraCharacteristics() generates
(Status status, CameraMetadata cameraCharacteristics);

/**
* setTorchMode:
*
* Turn on or off the torch mode of the flash unit associated with this
* camera device. If the operation is successful, HAL must notify the
* framework torch state by invoking
* ICameraProviderCallback::torchModeStatusChange() with the new state.
*
* An active camera session has a higher priority accessing the flash
* unit. When there are any resource conflicts, such as when open() is
* called to fully activate a camera device, the provider must notify the
* framework through ICameraProviderCallback::torchModeStatusChange() that
* the torch mode has been turned off and the torch mode state has become
* TORCH_MODE_STATUS_NOT_AVAILABLE. When resources to turn on torch mode
* become available again, the provider must notify the framework through
* ICameraProviderCallback::torchModeStatusChange() that the torch mode
* state has become TORCH_MODE_STATUS_AVAILABLE_OFF for set_torch_mode() to
* be called.
*
* When the client calls setTorchMode() to turn on the torch mode of a flash
* unit, if the HAL cannot keep multiple torch modes on simultaneously, the
* HAL must turn off the torch mode(s) that were turned on by previous
* setTorchMode() calls and notify the framework that the torch mode state
* of those flash unit(s) has become TORCH_MODE_STATUS_AVAILABLE_OFF.
*
* @param torchMode The new mode to set the device flash unit to.
*
* @return status Status code for the operation, one of:
* OK:
* On a successful change to the torch state
* INTERNAL_ERROR:
* The flash unit cannot be operated due to an unexpected internal
* error.
* ILLEGAL_ARGUMENT:
* The camera ID is unknown.
* CAMERA_IN_USE:
* This camera device has been opened, so the torch cannot be
* controlled until it is closed.
* MAX_CAMERAS_IN_USE:
* Due to other camera devices being open, or due to other
* resource constraints, the torch cannot be controlled currently.
* METHOD_NOT_SUPPORTED:
* This provider does not support direct operation of flashlight
* torch mode. The framework must open the camera device and turn
* the torch on through the device interface.
* OPERATION_NOT_SUPPORTED:
* This camera device does not have a flash unit. This can
* be returned if and only if android.flash.info.available is
* false.
* CAMERA_DISCONNECTED:
* An external camera device has been disconnected, and is no longer
* available. This camera device interface is now stale, and a new
* instance must be acquired if the device is reconnected. All
* subsequent calls on this interface must return
* CAMERA_DISCONNECTED.
*
*/
setTorchMode(TorchMode mode) generates (Status status);

/**
* open:
*
* Power on and initialize this camera device for active use, returning a
* session handle for active operations.
*
* @param callback Interface to invoke by the HAL for device asynchronous
* events. For HALs newer than version 3.2, HAL must use castFrom
* method to check the exact version of callback sent by camera service.
*
* @return status Status code for the operation, one of:
* OK:
* On a successful open of the camera device.
* INTERNAL_ERROR:
* The camera device cannot be opened due to an internal
* error.
* ILLEGAL_ARGUMENT:
* The callbacks handle is invalid (for example, it is null).
* CAMERA_IN_USE:
* This camera device is already open.
* MAX_CAMERAS_IN_USE:
* The maximal number of camera devices that can be
* opened concurrently were opened already.
* CAMERA_DISCONNECTED:
* This external camera device has been disconnected, and is no
* longer available. This interface is now stale, and a new instance
* must be acquired if the device is reconnected. All subsequent
* calls on this interface must return CAMERA_DISCONNECTED.
* @return session The interface to the newly-opened camera session,
* or null if status is not OK.
*/
open(ICameraDeviceCallback callback) generates
(Status status, ICameraDeviceSession session);

/**
* dumpState:
*
* Print out debugging state for the camera device. This may be called by
* the framework when the camera service is asked for a debug dump, which
* happens when using the dumpsys tool, or when capturing a bugreport.
*
* The passed-in file descriptor can be used to write debugging text using
* dprintf() or write(). The text must be in ASCII encoding only.
*
* In case this camera device has been disconnected, the dump must not fail,
* but may simply print out 'Device disconnected' or equivalent.
*
* Performance requirements:
*
* This must be a non-blocking call. The HAL should return from this call
* in 1ms, must return from this call in 10ms. This call must avoid
* deadlocks, as it may be called at any point during camera operation.
* Any synchronization primitives used (such as mutex locks or semaphores)
* must be acquired with a timeout.
*/
dumpState(handle fd);

};

该文件中定义了ICameraDevice接口类,由CameraDevice::TrampolineDeviceInterface_3_2实现,其主要接口如下:

  • open: 用于创建一个Camera设备,并且将Camera Service中继承ICameraDeviceCallback并实现了相应接口的Camera3Device作为参数传入Provider中,供Provider上传事件或者图像数据。
  • getCameraCharacteristics:用于获取Camera设备的属性。

2.4 ICameraDeviceCallback.hal

ICameraDeviceCallback.hal源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package android.hardware.camera.device@3.2;

import android.hardware.camera.common@1.0::types;

/**
*
* Callback methods for the HAL to call into the framework.
*
* These methods are used to return metadata and image buffers for a completed
* or failed captures, and to notify the framework of asynchronous events such
* as errors.
*
* The framework must not call back into the HAL from within these callbacks,
* and these calls must not block for extended periods.
*
*/
interface ICameraDeviceCallback {

/**
* processCaptureResult:
*
* Send results from one or more completed or partially completed captures
* to the framework.
* processCaptureResult() may be invoked multiple times by the HAL in
* response to a single capture request. This allows, for example, the
* metadata and low-resolution buffers to be returned in one call, and
* post-processed JPEG buffers in a later call, once it is available. Each
* call must include the frame number of the request it is returning
* metadata or buffers for. Only one call to processCaptureResult
* may be made at a time by the HAL although the calls may come from
* different threads in the HAL.
*
* A component (buffer or metadata) of the complete result may only be
* included in one process_capture_result call. A buffer for each stream,
* and the result metadata, must be returned by the HAL for each request in
* one of the processCaptureResult calls, even in case of errors producing
* some of the output. A call to processCaptureResult() with neither
* output buffers or result metadata is not allowed.
*
* The order of returning metadata and buffers for a single result does not
* matter, but buffers for a given stream must be returned in FIFO order. So
* the buffer for request 5 for stream A must always be returned before the
* buffer for request 6 for stream A. This also applies to the result
* metadata; the metadata for request 5 must be returned before the metadata
* for request 6.
*
* However, different streams are independent of each other, so it is
* acceptable and expected that the buffer for request 5 for stream A may be
* returned after the buffer for request 6 for stream B is. And it is
* acceptable that the result metadata for request 6 for stream B is
* returned before the buffer for request 5 for stream A is. If multiple
* capture results are included in a single call, camera framework must
* process results sequentially from lower index to higher index, as if
* these results were sent to camera framework one by one, from lower index
* to higher index.
*
* The HAL retains ownership of result structure, which only needs to be
* valid to access during this call.
*
* The output buffers do not need to be filled yet; the framework must wait
* on the stream buffer release sync fence before reading the buffer
* data. Therefore, this method should be called by the HAL as soon as
* possible, even if some or all of the output buffers are still in
* being filled. The HAL must include valid release sync fences into each
* output_buffers stream buffer entry, or -1 if that stream buffer is
* already filled.
*
* If the result buffer cannot be constructed for a request, the HAL must
* return an empty metadata buffer, but still provide the output buffers and
* their sync fences. In addition, notify() must be called with an
* ERROR_RESULT message.
*
* If an output buffer cannot be filled, its status field must be set to
* STATUS_ERROR. In addition, notify() must be called with a ERROR_BUFFER
* message.
*
* If the entire capture has failed, then this method still needs to be
* called to return the output buffers to the framework. All the buffer
* statuses must be STATUS_ERROR, and the result metadata must be an
* empty buffer. In addition, notify() must be called with a ERROR_REQUEST
* message. In this case, individual ERROR_RESULT/ERROR_BUFFER messages
* must not be sent.
*
* Performance requirements:
*
* This is a non-blocking call. The framework must handle each CaptureResult
* within 5ms.
*
* The pipeline latency (see S7 for definition) should be less than or equal to
* 4 frame intervals, and must be less than or equal to 8 frame intervals.
*
*/
processCaptureResult(vec<CaptureResult> results);

/**
* notify:
*
* Asynchronous notification callback from the HAL, fired for various
* reasons. Only for information independent of frame capture, or that
* require specific timing. Multiple messages may be sent in one call; a
* message with a higher index must be considered to have occurred after a
* message with a lower index.
*
* Multiple threads may call notify() simultaneously.
*
* Buffers delivered to the framework must not be dispatched to the
* application layer until a start of exposure timestamp (or input image's
* start of exposure timestamp for a reprocess request) has been received
* via a SHUTTER notify() call. It is highly recommended to dispatch this
* call as early as possible.
*
* The SHUTTER notify calls for requests with android.control.enableZsl
* set to TRUE and ANDROID_CONTROL_CAPTURE_INTENT == STILL_CAPTURE may be
* out-of-order compared to SHUTTER notify for other kinds of requests
* (including regular, reprocess, or zero-shutter-lag requests with
* different capture intents).
*
* As a result, the capture results of zero-shutter-lag requests with
* ANDROID_CONTROL_CAPTURE_INTENT == STILL_CAPTURE may be out-of-order
* compared to capture results for other kinds of requests.
*
* Different SHUTTER notify calls for zero-shutter-lag requests with
* ANDROID_CONTROL_CAPTURE_INTENT == STILL_CAPTURE must be in order between
* them, as is for other kinds of requests. SHUTTER notify calls for
* zero-shutter-lag requests with non STILL_CAPTURE intent must be in order
* with SHUTTER notify calls for regular requests.
* ------------------------------------------------------------------------
* Performance requirements:
*
* This is a non-blocking call. The framework must handle each message in 5ms.
*/
notify(vec<NotifyMsg> msgs);

};

该文件中定义了ICameraDeviceCallback接口类,由Camera Service中的Camera3Device继承并实现,通过调用ICameraDevice::open方法注册到Provider中,其主要接口如下:

  • processCaptureResult_3_4: 一旦有图像数据产生会通过调用该方法将数据以及meta data上传至Camera Service。
  • notify: 通过该方法上传事件至Camera Service中,比如shutter事件等。

2.5 ICameraDeviceSession.hal

ICameraDeviceSession.hal源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
package android.hardware.camera.device@3.2;

import android.hardware.camera.common@1.0::types;

/**
* Camera device active session interface.
*
* Obtained via ICameraDevice::open(), this interface contains the methods to
* configure and request captures from an active camera device.
*
*/
interface ICameraDeviceSession {

/**
* constructDefaultRequestSettings:
*
* Create capture settings for standard camera use cases.
*
* The device must return a settings buffer that is configured to meet the
* requested use case, which must be one of the CAMERA3_TEMPLATE_*
* enums. All request control fields must be included.
*
* Performance requirements:
*
* This must be a non-blocking call. The HAL should return from this call
* in 1ms, and must return from this call in 5ms.
*
* Return values:
* @return status Status code for the operation, one of:
* OK:
* On a successful construction of default settings.
* INTERNAL_ERROR:
* An unexpected internal error occurred, and the default settings
* are not available.
* ILLEGAL_ARGUMENT:
* The camera HAL does not support the input template type
* CAMERA_DISCONNECTED:
* An external camera device has been disconnected, and is no longer
* available. This camera device interface is now stale, and a new
* instance must be acquired if the device is reconnected. All
* subsequent calls on this interface must return
* CAMERA_DISCONNECTED.
* @return template The default capture request settings for the requested
* use case, or an empty metadata structure if status is not OK.
*
*/
constructDefaultRequestSettings(RequestTemplate type) generates
(Status status, CameraMetadata requestTemplate);

/**
* configureStreams:
*
* Reset the HAL camera device processing pipeline and set up new input and
* output streams. This call replaces any existing stream configuration with
* the streams defined in the streamList. This method must be called at
* least once before a request is submitted with processCaptureRequest().
*
* The streamList must contain at least one output-capable stream, and may
* not contain more than one input-capable stream.
*
* The streamList may contain streams that are also in the currently-active
* set of streams (from the previous call to configureStreams()). These
* streams must already have valid values for usage, maxBuffers, and the
* private pointer.
*
* If the HAL needs to change the stream configuration for an existing
* stream due to the new configuration, it may rewrite the values of usage
* and/or maxBuffers during the configure call.
*
* The framework must detect such a change, and may then reallocate the
* stream buffers before using buffers from that stream in a request.
*
* If a currently-active stream is not included in streamList, the HAL may
* safely remove any references to that stream. It must not be reused in a
* later configureStreams() call by the framework, and all the gralloc
* buffers for it must be freed after the configureStreams() call returns.
*
* If the stream is new, the client must set the consumer usage flags in
* requestedConfiguration. Upon return, the HAL device must set producerUsage,
* maxBuffers, and other fields in the configureStreams() return values. These
* fields are then used by the framework and the platform gralloc module to
* allocate the gralloc buffers for each stream.
*
* Newly allocated buffers may be included in a capture request at any time
* by the framework. Once a gralloc buffer is returned to the framework
* with processCaptureResult (and its respective releaseFence has been
* signaled) the framework may free or reuse it at any time.
*
* ------------------------------------------------------------------------
*
* Preconditions:
*
* The framework must only call this method when no captures are being
* processed. That is, all results have been returned to the framework, and
* all in-flight input and output buffers have been returned and their
* release sync fences have been signaled by the HAL. The framework must not
* submit new requests for capture while the configureStreams() call is
* underway.
*
* Postconditions:
*
* The HAL device must configure itself to provide maximum possible output
* frame rate given the sizes and formats of the output streams, as
* documented in the camera device's static metadata.
*
* Performance requirements:
*
* This call is expected to be heavyweight and possibly take several hundred
* milliseconds to complete, since it may require resetting and
* reconfiguring the image sensor and the camera processing pipeline.
* Nevertheless, the HAL device should attempt to minimize the
* reconfiguration delay to minimize the user-visible pauses during
* application operational mode changes (such as switching from still
* capture to video recording).
*
* The HAL should return from this call in 500ms, and must return from this
* call in 1000ms.
*
* @return Status Status code for the operation, one of:
* OK:
* On successful stream configuration.
* INTERNAL_ERROR:
* If there has been a fatal error and the device is no longer
* operational. Only close() can be called successfully by the
* framework after this error is returned.
* ILLEGAL_ARGUMENT:
* If the requested stream configuration is invalid. Some examples
* of invalid stream configurations include:
* - Including more than 1 INPUT stream
* - Not including any OUTPUT streams
* - Including streams with unsupported formats, or an unsupported
* size for that format.
* - Including too many output streams of a certain format.
* - Unsupported rotation configuration
* - Stream sizes/formats don't satisfy the
* StreamConfigurationMode requirements for non-NORMAL mode, or
* the requested operation_mode is not supported by the HAL.
* - Unsupported usage flag
* The camera service cannot filter out all possible illegal stream
* configurations, since some devices may support more simultaneous
* streams or larger stream resolutions than the minimum required
* for a given camera device hardware level. The HAL must return an
* ILLEGAL_ARGUMENT for any unsupported stream set, and then be
* ready to accept a future valid stream configuration in a later
* configureStreams call.
* @return finalConfiguration The stream parameters desired by the HAL for
* each stream, including maximum buffers, the usage flags, and the
* override format.
*
*/
configureStreams(StreamConfiguration requestedConfiguration)
generates (Status status,
HalStreamConfiguration halConfiguration);

/**
* processCaptureRequest:
*
* Send a list of capture requests to the HAL. The HAL must not return from
* this call until it is ready to accept the next set of requests to
* process. Only one call to processCaptureRequest() must be made at a time
* by the framework, and the calls must all be from the same thread. The
* next call to processCaptureRequest() must be made as soon as a new
* request and its associated buffers are available. In a normal preview
* scenario, this means the function is generally called again by the
* framework almost instantly. If more than one request is provided by the
* client, the HAL must process the requests in order of lowest index to
* highest index.
*
* The cachesToRemove argument contains a list of buffer caches (see
* StreamBuffer document for more information on buffer cache) to be removed
* by camera HAL. Camera HAL must remove these cache entries whether or not
* this method returns OK.
*
* The actual request processing is asynchronous, with the results of
* capture being returned by the HAL through the processCaptureResult()
* call. This call requires the result metadata to be available, but output
* buffers may simply provide sync fences to wait on. Multiple requests are
* expected to be in flight at once, to maintain full output frame rate.
*
* The framework retains ownership of the request structure. It is only
* guaranteed to be valid during this call. The HAL device must make copies
* of the information it needs to retain for the capture processing. The HAL
* is responsible for waiting on and closing the buffers' fences and
* returning the buffer handles to the framework.
*
* The HAL must write the file descriptor for the input buffer's release
* sync fence into input_buffer->release_fence, if input_buffer is not
* valid. If the HAL returns -1 for the input buffer release sync fence, the
* framework is free to immediately reuse the input buffer. Otherwise, the
* framework must wait on the sync fence before refilling and reusing the
* input buffer.
*
* The input/output buffers provided by the framework in each request
* may be brand new (having never before seen by the HAL).
*
* ------------------------------------------------------------------------
* Performance considerations:
*
* Handling a new buffer should be extremely lightweight and there must be
* no frame rate degradation or frame jitter introduced.
*
* This call must return fast enough to ensure that the requested frame
* rate can be sustained, especially for streaming cases (post-processing
* quality settings set to FAST). The HAL should return this call in 1
* frame interval, and must return from this call in 4 frame intervals.
*
* @return status Status code for the operation, one of:
* OK:
* On a successful start to processing the capture request
* ILLEGAL_ARGUMENT:
* If the input is malformed (the settings are empty when not
* allowed, there are 0 output buffers, etc) and capture processing
* cannot start. Failures during request processing must be
* handled by calling ICameraDeviceCallback::notify(). In case of
* this error, the framework retains responsibility for the
* stream buffers' fences and the buffer handles; the HAL must not
* close the fences or return these buffers with
* ICameraDeviceCallback::processCaptureResult().
* INTERNAL_ERROR:
* If the camera device has encountered a serious error. After this
* error is returned, only the close() method can be successfully
* called by the framework.
* @return numRequestProcessed Number of requests successfully processed by
* camera HAL. When status is OK, this must be equal to the size of
* requests. When the call fails, this number is the number of requests
* that HAL processed successfully before HAL runs into an error.
*
*/
processCaptureRequest(vec<CaptureRequest> requests,
vec<BufferCache> cachesToRemove)
generates (Status status, uint32_t numRequestProcessed);

/**
* getCaptureRequestMetadataQueue:
*
* Retrieves the queue used along with processCaptureRequest. If
* client decides to use fast message queue to pass request metadata,
* it must:
* - Call getCaptureRequestMetadataQueue to retrieve the fast message queue;
* - In each of the requests sent in processCaptureRequest, set
* fmqSettingsSize field of CaptureRequest to be the size to read from the
* fast message queue; leave settings field of CaptureRequest empty.
*
* @return queue the queue that client writes request metadata to.
*/
getCaptureRequestMetadataQueue() generates (fmq_sync<uint8_t> queue);

/**
* getCaptureResultMetadataQueue:
*
* Retrieves the queue used along with
* ICameraDeviceCallback.processCaptureResult.
*
* Clients to ICameraDeviceSession must:
* - Call getCaptureRequestMetadataQueue to retrieve the fast message queue;
* - In implementation of ICameraDeviceCallback, test whether
* .fmqResultSize field is zero.
* - If .fmqResultSize != 0, read result metadata from the fast message
* queue;
* - otherwise, read result metadata in CaptureResult.result.
*
* @return queue the queue that implementation writes result metadata to.
*/
getCaptureResultMetadataQueue() generates (fmq_sync<uint8_t> queue);

/**
* flush:
*
* Flush all currently in-process captures and all buffers in the pipeline
* on the given device. Generally, this method is used to dump all state as
* quickly as possible in order to prepare for a configure_streams() call.
*
* No buffers are required to be successfully returned, so every buffer
* held at the time of flush() (whether successfully filled or not) may be
* returned with CAMERA3_BUFFER_STATUS_ERROR. Note the HAL is still allowed
* to return valid (CAMERA3_BUFFER_STATUS_OK) buffers during this call,
* provided they are successfully filled.
*
* All requests currently in the HAL are expected to be returned as soon as
* possible. Not-in-process requests must return errors immediately. Any
* interruptible hardware blocks must be stopped, and any uninterruptible
* blocks must be waited on.
*
* flush() may be called concurrently to processCaptureRequest(), with the
* expectation that processCaptureRequest returns quickly and the
* request submitted in that processCaptureRequest call is treated like
* all other in-flight requests. Due to concurrency issues, it is possible
* that from the HAL's point of view, a processCaptureRequest() call may
* be started after flush has been invoked but has not returned yet. If such
* a call happens before flush() returns, the HAL must treat the new
* capture request like other in-flight pending requests (see #4 below).
*
* More specifically, the HAL must follow below requirements for various
* cases:
*
* 1. For captures that are too late for the HAL to cancel/stop, and must be
* completed normally by the HAL; i.e. the HAL can send shutter/notify
* and processCaptureResult and buffers as normal.
*
* 2. For pending requests that have not done any processing, the HAL must
* call notify CAMERA3_MSG_ERROR_REQUEST, and return all the output
* buffers with processCaptureResult in the error state
* (CAMERA3_BUFFER_STATUS_ERROR). The HAL must not place the release
* fence into an error state, instead, the release fences must be set to
* the acquire fences passed by the framework, or -1 if they have been
* waited on by the HAL already. This is also the path to follow for any
* captures for which the HAL already called notify() with
* CAMERA3_MSG_SHUTTER but won't be producing any metadata/valid buffers
* for. After CAMERA3_MSG_ERROR_REQUEST, for a given frame, only
* processCaptureResults with buffers in CAMERA3_BUFFER_STATUS_ERROR
* are allowed. No further notifys or processCaptureResult with
* non-empty metadata is allowed.
*
* 3. For partially completed pending requests that do not have all the
* output buffers or perhaps missing metadata, the HAL must follow
* below:
*
* 3.1. Call notify with CAMERA3_MSG_ERROR_RESULT if some of the expected
* result metadata (i.e. one or more partial metadata) won't be
* available for the capture.
*
* 3.2. Call notify with CAMERA3_MSG_ERROR_BUFFER for every buffer that
* won't be produced for the capture.
*
* 3.3. Call notify with CAMERA3_MSG_SHUTTER with the capture timestamp
* before any buffers/metadata are returned with
* processCaptureResult.
*
* 3.4. For captures that will produce some results, the HAL must not
* call CAMERA3_MSG_ERROR_REQUEST, since that indicates complete
* failure.
*
* 3.5. Valid buffers/metadata must be passed to the framework as
* normal.
*
* 3.6. Failed buffers must be returned to the framework as described
* for case 2. But failed buffers do not have to follow the strict
* ordering valid buffers do, and may be out-of-order with respect
* to valid buffers. For example, if buffers A, B, C, D, E are sent,
* D and E are failed, then A, E, B, D, C is an acceptable return
* order.
*
* 3.7. For fully-missing metadata, calling CAMERA3_MSG_ERROR_RESULT is
* sufficient, no need to call processCaptureResult with empty
* metadata or equivalent.
*
* 4. If a flush() is invoked while a processCaptureRequest() invocation
* is active, that process call must return as soon as possible. In
* addition, if a processCaptureRequest() call is made after flush()
* has been invoked but before flush() has returned, the capture request
* provided by the late processCaptureRequest call must be treated
* like a pending request in case #2 above.
*
* flush() must only return when there are no more outstanding buffers or
* requests left in the HAL. The framework may call configure_streams (as
* the HAL state is now quiesced) or may issue new requests.
*
* Note that it's sufficient to only support fully-succeeded and
* fully-failed result cases. However, it is highly desirable to support
* the partial failure cases as well, as it could help improve the flush
* call overall performance.
*
* Performance requirements:
*
* The HAL should return from this call in 100ms, and must return from this
* call in 1000ms. And this call must not be blocked longer than pipeline
* latency (see S7 for definition).
*
* @return status Status code for the operation, one of:
* OK:
* On a successful flush of the camera HAL.
* INTERNAL_ERROR:
* If the camera device has encountered a serious error. After this
* error is returned, only the close() method can be successfully
* called by the framework.
*/
flush() generates (Status status);

/**
* close:
*
* Shut down the camera device.
*
* After this call, all calls to this session instance must return
* INTERNAL_ERROR.
*
* This method must always succeed, even if the device has encountered a
* serious error.
*/
close();
};

该文件中定义了ICameraDeviceSession接口类,由CameraDeviceSession::TrampolineSessionInterface_3_2继承并实现,其主要接口如下:

  • constructDefaultRequestSettings:用于创建默认的Request配置项。
  • configureStreams_3_5:用于配置数据流,其中包括了output buffer/Surface/图像格式大小等属性。
  • processCaptureRequest_3_4:下发request到Provider中,一个request对应着一次图像需求。
  • close: 关闭当前会话。

三 、Camera Provider 主程序

打开camera时,可以看到cameraprovider进程,下面看下具体cameprovider如何启动的,以及整个进程如何运转。

下图是整个cameraprovider进程启动流程图,将会根据这个流程图进行分析

3.1 android.hardware.camera.provider@2.4-service_64.rc

在系统初始化的时候,系统会去运行android.hardware.camera.provider@2.4-service_64程序启动Provider进程

[->hardware\interfaces\camera\provider\2.4\default\android.hardware.camera.provider@2.4-service_64.rc]

1
2
3
4
5
6
7
8
service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service_64
interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
class hal
user cameraserver
group audio camera input drmrpc
ioprio rt 4
capabilities SYS_NICE
writepid /dev/cpuset/camera-daemon/tasks /dev/stune/foreground/tasks

3.2 service.cpp

下面先简单介绍下hidl服务启动的两个方式

直通式 HAL(passthrough)模式:编译成so库,供System分区的进程和应用直接加载调用,两者在同一个进程中;

绑定式HAL(Binderized )模式:直接编译成一个daemon可运行的服务,然后System分区的进程通过HwBinder的IPC通信方式来调用,两者在二个独立的进程中。

绑定式可以用两种方式来绑定服务,第一种通过defaultPassthroughServiceImplementation 的调用来注册服务,另外一种是直接调用RegisterAsService来注册服务。

CameraProvider是通过defaultPassthroughServiceImplementation 的调用来注册服务

[->hardware\interfaces\camera\provider\2.4\default\service.cpp]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifdef LAZY_SERVICE
#define LOG_TAG "android.hardware.camera.provider@2.4-service-lazy"
#else
#define LOG_TAG "android.hardware.camera.provider@2.4-service"
#endif

#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <binder/ProcessState.h>
#include <hidl/LegacySupport.h>

using android::status_t;
using android::hardware::defaultLazyPassthroughServiceImplementation;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::camera::provider::V2_4::ICameraProvider;

#ifdef LAZY_SERVICE
const bool kLazyService = true;
#else
const bool kLazyService = false;
#endif

int main()
{
ALOGI("CameraProvider@2.4 legacy service is starting.");
// The camera HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
status_t status;
if (kLazyService) {
status = defaultLazyPassthroughServiceImplementation<ICameraProvider>("legacy/0",
/*maxThreads*/ 6);
} else {
status = defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0",
/*maxThreads*/ 6);
}
return status;
}

在manifest中注册的provider,选择的是hwbinder,可知注册的方式是绑定式HAL(Binderized )模式

1
2
3
4
5
6
7
8
9
10
<hal format="hidl">
<name>android.hardware.camera.provider</name>
<transport>hwbinder</transport>
<version>2.4</version>
<interface>
<name>ICameraProvider</name>
<instance>legacy/0</instance>
<instance>external/0</instance>
</interface>
</hal>

[->system/libhidl/transport/include/hidl/LegacySupport.h]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/**
* Creates default passthrough service implementation. This method never returns.
*
* Return value is exit status.
*/
template <class Interface>
__attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
const std::string& name, size_t maxThreads = 1) {
configureRpcThreadpool(maxThreads, true);
status_t result = registerPassthroughServiceImplementation<Interface>(name);

if (result != OK) {
return result;
}

joinRpcThreadpool();
return UNKNOWN_ERROR;
}

/**
* Registers passthrough service implementation.
*/
template <class Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& name = "default") {
return details::registerPassthroughServiceImplementation<Interface>(
[](const sp<Interface>& service, const std::string& name) {
return service->registerAsService(name);
},
name);
}

template <class Interface, typename Func>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
Func registerServiceCb, const std::string& name = "default") {
sp<Interface> service = Interface::getService(name, true /* getStub */);

if (service == nullptr) {
ALOGE("Could not get passthrough implementation for %s/%s.",
Interface::descriptor, name.c_str());
return EXIT_FAILURE;
}

LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
Interface::descriptor, name.c_str());

status_t status = registerServiceCb(service, name);

if (status == OK) {
ALOGI("Registration complete for %s/%s.",
Interface::descriptor, name.c_str());
} else {
ALOGE("Could not register service %s/%s (%d).",
Interface::descriptor, name.c_str(), status);
}

return status;
}
} // namespace details

// 文件路径out\soong\.intermediates\hardware\interfaces\camera\provider\2.4\android.hardware.camera.provider@2.4_genc++\gen\android\hardware\camera\provider\2.4\CameraProviderAll.cpp

::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}

//system/libhidl/transport/include/hidl/HidlTransportSupport.h
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;

sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);

if (base == nullptr) {
return nullptr;
}

if (base->isRemote()) {
// getRawServiceInternal guarantees we get the proper class
return sp<IType>(new BpType(getOrCreateCachedBinder(base.get())));
}

return IType::castFrom(base);
}

} // namespace details

} /

//system\libhidl\transport\ServiceManagement.cpp
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
using ::android::hidl::manager::V1_0::IServiceManager;
sp<Waiter> waiter;

sp<IServiceManager1_1> sm;
Transport transport = Transport::EMPTY;
if (kIsRecovery) {
transport = Transport::PASSTHROUGH;
} else {
sm = defaultServiceManager1_1();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}

Return<Transport> transportRet = sm->getTransport(descriptor, instance);

if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s",
transportRet.description().c_str());
return nullptr;
}
transport = transportRet;
}

const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);

#ifdef ENFORCE_VINTF_MANIFEST

#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
#else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
const bool trebleTestingOverride = false;
const bool vintfLegacy = false;
#endif // LIBHIDL_TARGET_DEBUGGABLE

#else // not ENFORCE_VINTF_MANIFEST
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY);
#endif // ENFORCE_VINTF_MANIFEST

for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
if (waiter == nullptr && tries > 0) {
waiter = new Waiter(descriptor, instance, sm);
}
if (waiter != nullptr) {
waiter->reset(); // don't reorder this -- see comments on reset()
}
Return<sp<IBase>> ret = sm->get(descriptor, instance);
if (!ret.isOk()) {
ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
ret.description().c_str(), descriptor.c_str(), instance.c_str());
break;
}
sp<IBase> base = ret;
if (base != nullptr) {
Return<bool> canCastRet =
details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);

if (canCastRet.isOk() && canCastRet) {
if (waiter != nullptr) {
waiter->done();
}
return base; // still needs to be wrapped by Bp class.
}

if (!handleCastError(canCastRet, descriptor, instance)) break;
}

// In case of legacy or we were not asked to retry, don't.
if (vintfLegacy || !retry) break;

if (waiter != nullptr) {
ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
waiter->wait(true /* timeout */);
}
}

if (waiter != nullptr) {
waiter->done();
}

if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}

return nullptr;
}

sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
return manager;
}

truct PassthroughServiceManager : IServiceManager1_1 {
static void openLibs(
const std::string& fqName,
const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
const std::string& /* sym */)>& eachLib) {
//fqName looks like android.hardware.foo@1.0::IFoo
size_t idx = fqName.find("::");

if (idx == std::string::npos ||
idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
return;
}

std::string packageAndVersion = fqName.substr(0, idx);
std::string ifaceName = fqName.substr(idx + strlen("::"));

const std::string prefix = packageAndVersion + "-impl";
// sym为 HIDL_FETCH_ICameraProvider
const std::string sym = "HIDL_FETCH_" + ifaceName;

constexpr int dlMode = RTLD_LAZY;
void* handle = nullptr;

dlerror(); // clear

static std::string halLibPathVndkSp = android::base::StringPrintf(
HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
std::vector<std::string> paths = {
HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR, halLibPathVndkSp,
#ifndef __ANDROID_VNDK__
HAL_LIBRARY_PATH_SYSTEM,
#endif
};

#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
if (trebleTestingOverride) {
// Load HAL implementations that are statically linked
handle = dlopen(nullptr, dlMode);
if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen self: "
<< (error == nullptr ? "unknown error" : error);
} else if (!eachLib(handle, "SELF", sym)) {
return;
}

const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
if (vtsRootPath && strlen(vtsRootPath) > 0) {
const std::string halLibraryPathVtsOverride =
std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
paths.insert(paths.begin(), halLibraryPathVtsOverride);
}
}
#endif

for (const std::string& path : paths) {
std::vector<std::string> libs = findFiles(path, prefix, ".so");

for (const std::string &lib : libs) {
const std::string fullPath = path + lib;

if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
#if !defined(__ANDROID_RECOVERY__)
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
}

if (handle == nullptr) {
const char* error = dlerror();
LOG(ERROR) << "Failed to dlopen " << lib << ": "
<< (error == nullptr ? "unknown error" : error);
continue;
}

if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}


Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> ret = nullptr;

openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
IBase* (*generator)(const char* name);
// 通过dlsym在android.hardware.camera.provider@2.4-impl.so中找到HIDL_FETCH_ICameraProvider的地址
*(void **)(&generator) = dlsym(handle, sym.c_str());
if(!generator) {
const char* error = dlerror();
LOG(ERROR) << "Passthrough lookup opened " << lib
<< " but could not find symbol " << sym << ": "
<< (error == nullptr ? "unknown error" : error);
dlclose(handle);
return true;
}
// 执行HIDL_FETCH_ICameraProvider函数,参数为legacy/0
ret = (*generator)(name.c_str());

if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}

// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});

return ret;
}

3.3 CameraProvider_2_4.cpp

上面最后调用到HIDL_FETCH_ICameraProvider,通过这个方法实例化LegacyCameraProviderImpl_2_4

[->hardware\interfaces\camera\provider\2.4\default\CameraProvider_2_4.cpp]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "CameraProvider_2_4.h"
#include "LegacyCameraProviderImpl_2_4.h"
#include "ExternalCameraProviderImpl_2_4.h"

const char *kLegacyProviderName = "legacy/0";
const char *kExternalProviderName = "external/0";

namespace android {
namespace hardware {
namespace camera {
namespace provider {
namespace V2_4 {
namespace implementation {

using android::hardware::camera::provider::V2_4::ICameraProvider;

extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name);

template<typename IMPL>
CameraProvider<IMPL>* getProviderImpl() {
CameraProvider<IMPL> *provider = new CameraProvider<IMPL>();
if (provider == nullptr) {
ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
return nullptr;
}
if (provider->isInitFailed()) {
ALOGE("%s: camera provider init failed!", __FUNCTION__);
delete provider;
return nullptr;
}
return provider;
}

ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
using namespace android::hardware::camera::provider::V2_4::implementation;
ICameraProvider* provider = nullptr;
if (strcmp(name, kLegacyProviderName) == 0) {
provider = getProviderImpl<LegacyCameraProviderImpl_2_4>();
} else if (strcmp(name, kExternalProviderName) == 0) {
provider = getProviderImpl<ExternalCameraProviderImpl_2_4>();
} else {
ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
}

return provider;
}

} // namespace implementation
} // namespace V2_4
} // namespace provider
} // namespace camera
} // namespace hardware
} // namespace android

3.4 LegacyCameraProviderImpl_2_4初始化

其构造函数中通过hw_get_module标准方法获取HAL的camera_module_t结构体,并将其存入CameraModule对象中,之后通过调用该camera_modult_t结构体的init方法初始化HAL Module,紧接着调用其get_number_of_camera方法获取当前HAL支持的Camera数量,最后通过调用其set_callbacks方法将LegcyCameraProviderImpl_2_4(LegcyCameraProviderImpl_2_4继承了camera_modult_callback_t)作为参数传入CamX-CHI中,接受来自CamX-CHI中的数据以及事件,当这一系列动作完成了之后,Camera Provider进程便一直便存在于系统中,监听着来自Camera Service的调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
LegacyCameraProviderImpl_2_4::LegacyCameraProviderImpl_2_4() :
camera_module_callbacks_t({sCameraDeviceStatusChange,
sTorchModeStatusChange}) {
mInitFailed = initialize();
}


bool LegacyCameraProviderImpl_2_4::initialize() {
camera_module_t *rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}

mModule = new CameraModule(rawModule);
err = mModule->init();
if (err != OK) {
ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());

// Setup vendor tags here so HAL can setup vendor keys in camera characteristics
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
if (!setUpVendorTags()) {
ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
}

// Setup callback now because we are going to try openLegacy next


mPreferredHal3MinorVersion =
property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
switch(mPreferredHal3MinorVersion) {
case 2:
case 3:
// OK
break;
default:
ALOGW("Unknown minor camera device HAL version %d in property "
"'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
mPreferredHal3MinorVersion);
mPreferredHal3MinorVersion = 3;
}

mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
uint32_t device_version;
auto rc = mModule->getCameraDeviceVersion(i, &device_version);
if (rc != NO_ERROR) {
ALOGE("%s: Camera device version query failed!", __func__);
mModule.clear();
return true;
}

if (checkCameraVersion(i, device_version) != OK) {
ALOGE("%s: Camera version check failed!", __func__);
mModule.clear();
return true;
}

char cameraId[kMaxCameraIdLen];
snprintf(cameraId, sizeof(cameraId), "%d", i);
std::string cameraIdStr(cameraId);
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
addDeviceNames(i);
}
err = mModule->setCallbacks(this);
if (err != OK)
{
ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
mModule.clear();
return true;
}
return false; // mInitFailed
}

3.5 获取CameraDevice

在深入理解Android Camera架构二中3.1.7.2获取ICameraDevice的接口

3.5.1 getCameraDeviceInterface_V3_x

1
2
3
4
5
6
7
8
9
10
 const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
if (interface == nullptr) {
return nullptr;
}
//获取Provider端的ICameraDevice代理
ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Status s, sp<device::V3_2::ICameraDevice> interface) {
status = s;
cameraInterface = interface;
});

3.5.2 new CameraDevice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
const hidl_string& cameraDeviceName,
ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
std::string cameraId, deviceVersion;
bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
if (!match) {
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}

std::string deviceName(cameraDeviceName.c_str());
ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
Status status = Status::OK;
ssize_t idx = mCameraIds.indexOf(cameraId);
if (idx == NAME_NOT_FOUND) {
ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
status = Status::ILLEGAL_ARGUMENT;
} else { // invalid version
ALOGE("%s: camera device %s does not support version %s!",
__FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
status = Status::OPERATION_NOT_SUPPORTED;
}
_hidl_cb(status, nullptr);
return Void();
}

if (mCameraStatusMap.count(cameraId) == 0 ||
mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}

sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl;

// ICameraDevice 3.4 or upper
if (deviceVersion >= kHAL3_4) {
ALOGV("Constructing v3.4+ camera device");
if (deviceVersion == kHAL3_4) {
deviceImpl = new android::hardware::camera::device::V3_4::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
} else if (deviceVersion == kHAL3_5) {
deviceImpl = new android::hardware::camera::device::V3_5::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
}
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
IF_ALOGV() {
deviceImpl->getInterface()->interfaceChain([](
::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
ALOGV("Device interface chain:");
for (auto iface : interfaceChain) {
ALOGV(" %s", iface.c_str());
}
});
}
_hidl_cb (Status::OK, deviceImpl->getInterface());
return Void();
}

// ICameraDevice 3.2 and 3.3
// Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
// to the newest possible Treble HAL revision, but allow for override if needed via
// system property.
switch (mPreferredHal3MinorVersion) {
case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
ALOGV("Constructing v3.2 camera device");
deviceImpl = new android::hardware::camera::device::V3_2::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
break;
}
case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
ALOGV("Constructing v3.3 camera device");
deviceImpl = new android::hardware::camera::device::V3_3::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
break;
}
default:
ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}

_hidl_cb (Status::OK, deviceImpl->getInterface());
return Void();
}

3.5.3 deviceImpl->getInterface

[->hardware\interfaces\camera\device\3.2]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
CameraDevice::CameraDevice(
sp<CameraModule> module, const std::string& cameraId,
const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames) :
mModule(module),
mCameraId(cameraId),
mDisconnected(false),
mCameraDeviceNames(cameraDeviceNames) {
mCameraIdInt = atoi(mCameraId.c_str());
// Should not reach here as provider also validate ID
if (mCameraIdInt < 0) {
ALOGE("%s: Invalid camera id: %s", __FUNCTION__, mCameraId.c_str());
mInitFail = true;
} else if (mCameraIdInt >= mModule->getNumberOfCameras()) {
ALOGI("%s: Adding a new camera id: %s", __FUNCTION__, mCameraId.c_str());
}

mDeviceVersion = mModule->getDeviceVersion(mCameraIdInt);
if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
ALOGE("%s: Camera id %s does not support HAL3.2+",
__FUNCTION__, mCameraId.c_str());
mInitFail = true;
}
}

virtual sp<ICameraDevice> getInterface() {
return new TrampolineDeviceInterface_3_2(this);
}

struct TrampolineDeviceInterface_3_2 : public ICameraDevice {
TrampolineDeviceInterface_3_2(sp<CameraDevice> parent) :
mParent(parent) {}

virtual Return<void> getResourceCost(V3_2::ICameraDevice::getResourceCost_cb _hidl_cb)
override {
return mParent->getResourceCost(_hidl_cb);
}
...
}

3.6 open

在深入理解Android Camera架构二中3.2.2.4中调用provider的open方法

1
2
3
4
5
6
7
8
9
10
11
12
13
auto interface = deviceInfo3->startDeviceInterface<
CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
if (interface == nullptr) {
return DEAD_OBJECT;
}

ret = interface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});

3.6.1 CameraDevice::open

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,
ICameraDevice::open_cb _hidl_cb) {
Status status = initStatus();
sp<CameraDeviceSession> session = nullptr;

if (callback == nullptr) {
ALOGE("%s: cannot open camera %s. callback is null!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}

if (status != Status::OK) {
// Provider will never pass initFailed device to client, so
// this must be a disconnected camera
ALOGE("%s: cannot open camera %s. camera is disconnected!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
return Void();
} else {
mLock.lock();

ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
session = mSession.promote();
if (session != nullptr && !session->isClosed()) {
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
mLock.unlock();
_hidl_cb(Status::CAMERA_IN_USE, nullptr);
return Void();
}

/** Open HAL device */
status_t res;
camera3_device_t *device;

ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();

if (res != OK) {
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
mLock.unlock();
_hidl_cb(getHidlStatus(res), nullptr);
return Void();
}

/** Cross-check device version */
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
ALOGE("%s: Could not open camera: "
"Camera device should be at least %x, reports %x instead",
__FUNCTION__,
CAMERA_DEVICE_API_VERSION_3_2,
device->common.version);
device->common.close(&device->common);
mLock.unlock();
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}

struct camera_info info;
res = mModule->getCameraInfo(mCameraIdInt, &info);
if (res != OK) {
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
device->common.close(&device->common);
mLock.unlock();
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}

session = createSession(
device, info.static_camera_characteristics, callback);
if (session == nullptr) {
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
if (session->isInitFailed()) {
ALOGE("%s: camera device session init failed", __FUNCTION__);
session = nullptr;
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
mSession = session;

IF_ALOGV() {
session->getInterface()->interfaceChain([](
::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
ALOGV("Session interface chain:");
for (const auto& iface : interfaceChain) {
ALOGV(" %s", iface.c_str());
}
});
}
mLock.unlock();
}
_hidl_cb(status, session->getInterface());
return Void();
}

3.6.2 createSession

1
2
3
4
5
sp<CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device,
const camera_metadata_t* deviceInfo,
const sp<ICameraDeviceCallback>& callback) {
return new CameraDeviceSession(device, deviceInfo, callback);
}

3.6.3 new CameraDeviceSession

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
struct CameraDeviceSession : public virtual RefBase, protected camera3_callback_ops  {

CameraDeviceSession(camera3_device_t*,
const camera_metadata_t* deviceInfo,
const sp<ICameraDeviceCallback>&);
virtual ~CameraDeviceSession();
// Call by CameraDevice to dump active device states
void dumpState(const native_handle_t* fd);
// Caller must use this method to check if CameraDeviceSession ctor failed
bool isInitFailed() { return mInitFail; }
// Used by CameraDevice to signal external camera disconnected
void disconnect();
bool isClosed();

// Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
// dealing with minor version revs and simultaneous implementation and interface inheritance
virtual sp<ICameraDeviceSession> getInterface() {
return new TrampolineSessionInterface_3_2(this);
}
...
}

CameraDeviceSession::CameraDeviceSession(
camera3_device_t* device,
const camera_metadata_t* deviceInfo,
const sp<ICameraDeviceCallback>& callback) :
camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}),
mDevice(device),
mDeviceVersion(device->common.version),
mFreeBufEarly(shouldFreeBufEarly()),
mIsAELockAvailable(false),
mDerivePostRawSensKey(false),
mNumPartialResults(1),
mResultBatcher(callback) {
mDeviceInfo = deviceInfo;
camera_metadata_entry partialResultsCount =
mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
if (partialResultsCount.count > 0) {
mNumPartialResults = partialResultsCount.data.i32[0];
}
mResultBatcher.setNumPartialResults(mNumPartialResults);

camera_metadata_entry aeLockAvailableEntry = mDeviceInfo.find(
ANDROID_CONTROL_AE_LOCK_AVAILABLE);
if (aeLockAvailableEntry.count > 0) {
mIsAELockAvailable = (aeLockAvailableEntry.data.u8[0] ==
ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
}

// Determine whether we need to derive sensitivity boost values for older devices.
// If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control
// be listed (as the default value 100)
if (mDeviceInfo.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE)) {
mDerivePostRawSensKey = true;
}

mInitFail = initialize();
}

3.6.4 CameraDeviceSession::initialize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
bool CameraDeviceSession::initialize() {
/** Initialize device with callback functions */
ATRACE_BEGIN("camera3->initialize");
status_t res = mDevice->ops->initialize(mDevice, this);
ATRACE_END();

if (res != OK) {
ALOGE("%s: Unable to initialize HAL device: %s (%d)",
__FUNCTION__, strerror(-res), res);
mDevice->common.close(&mDevice->common);
mClosed = true;
return true;
}

// "ro.camera" properties are no longer supported on vendor side.
// Support a fall back for the fmq size override that uses "ro.vendor.camera"
// properties.
int32_t reqFMQSize = property_get_int32("ro.vendor.camera.req.fmq.size", /*default*/-1);
if (reqFMQSize < 0) {
reqFMQSize = property_get_int32("ro.camera.req.fmq.size", /*default*/-1);
if (reqFMQSize < 0) {
reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
} else {
ALOGV("%s: request FMQ size overridden to %d", __FUNCTION__, reqFMQSize);
}
} else {
ALOGV("%s: request FMQ size overridden to %d via fallback property", __FUNCTION__,
reqFMQSize);
}

mRequestMetadataQueue = std::make_unique<RequestMetadataQueue>(
static_cast<size_t>(reqFMQSize),
false /* non blocking */);
if (!mRequestMetadataQueue->isValid()) {
ALOGE("%s: invalid request fmq", __FUNCTION__);
return true;
}

// "ro.camera" properties are no longer supported on vendor side.
// Support a fall back for the fmq size override that uses "ro.vendor.camera"
// properties.
int32_t resFMQSize = property_get_int32("ro.vendor.camera.res.fmq.size", /*default*/-1);
if (resFMQSize < 0) {
resFMQSize = property_get_int32("ro.camera.res.fmq.size", /*default*/-1);
if (resFMQSize < 0) {
resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
} else {
ALOGV("%s: result FMQ size overridden to %d", __FUNCTION__, resFMQSize);
}
} else {
ALOGV("%s: result FMQ size overridden to %d via fallback property", __FUNCTION__,
resFMQSize);
}

mResultMetadataQueue = std::make_shared<RequestMetadataQueue>(
static_cast<size_t>(resFMQSize),
false /* non blocking */);
if (!mResultMetadataQueue->isValid()) {
ALOGE("%s: invalid result fmq", __FUNCTION__);
return true;
}
mResultBatcher.setResultMetadataQueue(mResultMetadataQueue);

return false;
}

3.7 configureStreams

Camera3Device通过接口最终调用CameraDeviceSession中的configureStreams方法

1
2
3
4
5
virtual Return<void> configureStreams(
const V3_2::StreamConfiguration& requestedConfiguration,
V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
return mParent->configureStreams(requestedConfiguration, _hidl_cb);
}

3.7.1 TrampolineSessionInterface_3_2::configureStreams

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
mParent(parent) {}

virtual Return<void> constructDefaultRequestSettings(
V3_2::RequestTemplate type,
V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
return mParent->constructDefaultRequestSettings(type, _hidl_cb);
}

virtual Return<void> configureStreams(
const V3_2::StreamConfiguration& requestedConfiguration,
V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
return mParent->configureStreams(requestedConfiguration, _hidl_cb);
}
...
}

3.7.2 CameraDeviceSession::configureStreams

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Return<void> CameraDeviceSession::configureStreams(
const StreamConfiguration& requestedConfiguration,
ICameraDeviceSession::configureStreams_cb _hidl_cb) {
Status status = initStatus();
HalStreamConfiguration outStreams;

// hold the inflight lock for entire configureStreams scope since there must not be any
// inflight request/results during stream configuration.
Mutex::Autolock _l(mInflightLock);
if (!mInflightBuffers.empty()) {
ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
__FUNCTION__, mInflightBuffers.size());
_hidl_cb(Status::INTERNAL_ERROR, outStreams);
return Void();
}

if (!mInflightAETriggerOverrides.empty()) {
ALOGE("%s: trying to configureStreams while there are still %zu inflight"
" trigger overrides!", __FUNCTION__,
mInflightAETriggerOverrides.size());
_hidl_cb(Status::INTERNAL_ERROR, outStreams);
return Void();
}

if (!mInflightRawBoostPresent.empty()) {
ALOGE("%s: trying to configureStreams while there are still %zu inflight"
" boost overrides!", __FUNCTION__,
mInflightRawBoostPresent.size());
_hidl_cb(Status::INTERNAL_ERROR, outStreams);
return Void();
}

if (status != Status::OK) {
_hidl_cb(status, outStreams);
return Void();
}

camera3_stream_configuration_t stream_list{};
hidl_vec<camera3_stream_t*> streams;
if (!preProcessConfigurationLocked(requestedConfiguration, &stream_list, &streams)) {
_hidl_cb(Status::INTERNAL_ERROR, outStreams);
return Void();
}

ATRACE_BEGIN("camera3->configure_streams");
status_t ret = mDevice->ops->configure_streams(mDevice, &stream_list);
ATRACE_END();

// In case Hal returns error most likely it was not able to release
// the corresponding resources of the deleted streams.
if (ret == OK) {
postProcessConfigurationLocked(requestedConfiguration);
} else {
postProcessConfigurationFailureLocked(requestedConfiguration);
}

if (ret == -EINVAL) {
status = Status::ILLEGAL_ARGUMENT;
} else if (ret != OK) {
status = Status::INTERNAL_ERROR;
} else {
convertToHidl(stream_list, &outStreams);
mFirstRequest = true;
}

_hidl_cb(status, outStreams);
return Void();
}

其他processCaptureRequest流程和上面一样

3.8 总结

在系统初始化的时候,系统会去运行android.hardware.camera.provider@2.4-service_64程序启动Provider进程,并加入HW Service Manager中接受统一管理,在该过程中实例化了一个LegacyCameraProviderImpl_2_4对象,并在其构造函数中通过hw_get_module标准方法获取HAL的camera_module_t结构体,并将其存入CameraModule对象中,之后通过调用该camera_modult_t结构体的init方法初始化HAL Module,紧接着调用其get_number_of_camera方法获取当前HAL支持的Camera数量,最后通过调用其set_callbacks方法将LegcyCameraProviderImpl_2_4(LegcyCameraProviderImpl_2_4继承了camera_modult_callback_t)作为参数传入CamX-CHI中,接受来自CamX-CHI中的数据以及事件,当这一系列动作完成了之后,Camera Provider进程便一直便存在于系统中,监听着来自Camera Service的调用。

接下来以上图为例简单介绍下Provider中几个重要流程:

  • Camera Service通过调用ICameraProvider的getCameraDeviceInterface_v3_x接口获取ICameraDevice,在此过程中,Provider会去实例化一个CameraDevice对象,并且将之前存有camera_modult_t结构体的CameraModule对象传入CameraDevice中,这样就可以在CameraDevice内部通过CameraModule访问到camera_module_t的相关资源,然后将CameraDevice内部类TrampolineDeviceInterface_3_2(该类继承并实现了ICameraDevice接口)返回给Camera Service。
  • Camera Service通过之前获取的ICameraDevice,调用其open方法来打开Camera设备,接着在Provider中会去调用CameraDevice对象的open方法,在该方法内部会去调用camera_module_t结构体的open方法,从而获取到HAL部分的camera3_device_t结构体,紧接着Provider会实例化一个CameraDeviceSession对象,并且将刚才获取到的camera3_device_t结构体以参数的方式传入CameraDeviceSession中,在CameraDeviceSession的构造方法中又会调用CameraDeviceSession的initialize方法,在该方法内部又会去调用camera3_device_t结构体的ops内的initialize方法开始HAL部分的初始化工作,最后CameraDeviceSession对象被作为camera3_callback_ops的实现传入HAL,接收来自HAL的数据或者具体事件,当一切动作都完成后,Provider会将CameraDeviceSession::TrampolineSessionInterface_3_2(该类继承并实现了ICameraDeviceSession接口)对象通过HIDL回调的方法返回给Camera Service中。
  • Camera Service通过调用ICameraDevcieSession的configureStreams_3_5接口进行数据流的配置,在Provider中,最终会通过调用之前获取的camera3_device_t结构体内ops的configure_streams方法下发到HAL中进行处理。
  • Camera Service通过调用ICameraDevcieSession的processCaptureRequest_3_4接口下发request请求到Provider中,在Provider中,最终依然会通过调用获取的camera3_device_t结构体内ops中的process_capture_request方法将此次请求下发到HAL中进行处理。

从整个流程不难看出,这几个接口最终对应的是HAL3的接口,并且Provider并没有经过太多复杂的额外的处理。

四、Camera HAL3接口

HAL硬件抽象层(Hardware Abstraction Layer),是谷歌开发的用于屏蔽底层硬件抽象出来的一个软件层, 每一个平台厂商可以将不开源的代码封装在这一层,仅仅提供二进制文件。

该层定义了自己的一套通用标准接口,平台厂商务必按照以下规则定义自己的Module:

每一个硬件模块都通过hw_module_t来描述,具有固定的名字HMI

每一个硬件模块都必须实现hw_module_t里面的open方法,用于打开硬件设备,并返回对应的操作接口集合

硬件的操作接口集合使用hw_device_t 来描述,并可以通过自定义一个更大的包含hw_device_t的结构体来拓展硬件操作集合

其中代表硬件模块的是hw_module_t,对应的设备是通过hw_device_t来描述,这两者的定义如下:

[->hardware\libhardware\include\hardware\hardware.h]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H
#define ANDROID_INCLUDE_HARDWARE_HARDWARE_H

#include <stdint.h>
#include <sys/cdefs.h>

#include <cutils/native_handle.h>
#include <system/graphics.h>

__BEGIN_DECLS

/*
* Value for the hw_module_t.tag field
*/

#define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))

#define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T')
#define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T')

#define HARDWARE_MAKE_API_VERSION(maj,min) \
((((maj) & 0xff) << 8) | ((min) & 0xff))

#define HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) \
((((maj) & 0xff) << 24) | (((min) & 0xff) << 16) | ((hdr) & 0xffff))
#define HARDWARE_API_VERSION_2_MAJ_MIN_MASK 0xffff0000
#define HARDWARE_API_VERSION_2_HEADER_MASK 0x0000ffff


/*
* The current HAL API version.
*
* All module implementations must set the hw_module_t.hal_api_version field
* to this value when declaring the module with HAL_MODULE_INFO_SYM.
*
* Note that previous implementations have always set this field to 0.
* Therefore, libhardware HAL API will always consider versions 0.0 and 1.0
* to be 100% binary compatible.
*
*/
#define HARDWARE_HAL_API_VERSION HARDWARE_MAKE_API_VERSION(1, 0)

/*
* Helper macros for module implementors.
*
* The derived modules should provide convenience macros for supported
* versions so that implementations can explicitly specify module/device
* versions at definition time.
*
* Use this macro to set the hw_module_t.module_api_version field.
*/
#define HARDWARE_MODULE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min)
#define HARDWARE_MODULE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr)

/*
* Use this macro to set the hw_device_t.version field
*/
#define HARDWARE_DEVICE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min)
#define HARDWARE_DEVICE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr)

struct hw_module_t;
struct hw_module_methods_t;
struct hw_device_t;

/**
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
* and the fields of this data structure must begin with hw_module_t
* followed by module specific information.
*/
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */
uint32_t tag;

/**
* The API version of the implemented module. The module owner is
* responsible for updating the version when a module interface has
* changed.
*
* The derived modules such as gralloc and audio own and manage this field.
* The module user must interpret the version field to decide whether or
* not to inter-operate with the supplied module implementation.
* For example, SurfaceFlinger is responsible for making sure that
* it knows how to manage different versions of the gralloc-module API,
* and AudioFlinger must know how to do the same for audio-module API.
*
* The module API version should include a major and a minor component.
* For example, version 1.0 could be represented as 0x0100. This format
* implies that versions 0x0100-0x01ff are all API-compatible.
*
* In the future, libhardware will expose a hw_get_module_version()
* (or equivalent) function that will take minimum/maximum supported
* versions as arguments and would be able to reject modules with
* versions outside of the supplied range.
*/
uint16_t module_api_version;
#define version_major module_api_version
/**
* version_major/version_minor defines are supplied here for temporary
* source code compatibility. They will be removed in the next version.
* ALL clients must convert to the new version format.
*/

/**
* The API version of the HAL module interface. This is meant to
* version the hw_module_t, hw_module_methods_t, and hw_device_t
* structures and definitions.
*
* The HAL interface owns this field. Module users/implementations
* must NOT rely on this value for version information.
*
* Presently, 0 is the only valid value.
*/
uint16_t hal_api_version;
#define version_minor hal_api_version

/** Identifier of module */
const char *id;

/** Name of this module */
const char *name;

/** Author/owner/implementor of the module */
const char *author;

/** Modules methods */
struct hw_module_methods_t* methods;

/** module's dso */
void* dso;

#ifdef __LP64__
uint64_t reserved[32-7];
#else
/** padding to 128 bytes, reserved for future use */
uint32_t reserved[32-7];
#endif

} hw_module_t;

typedef struct hw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);

} hw_module_methods_t;

/**
* Every device data structure must begin with hw_device_t
* followed by module specific public methods and attributes.
*/
typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */
uint32_t tag;

/**
* Version of the module-specific device API. This value is used by
* the derived-module user to manage different device implementations.
*
* The module user is responsible for checking the module_api_version
* and device version fields to ensure that the user is capable of
* communicating with the specific module implementation.
*
* One module can support multiple devices with different versions. This
* can be useful when a device interface changes in an incompatible way
* but it is still necessary to support older implementations at the same
* time. One such example is the Camera 2.0 API.
*
* This field is interpreted by the module user and is ignored by the
* HAL interface itself.
*/
uint32_t version;

/** reference to the module this device belongs to */
struct hw_module_t* module;

/** padding reserved for future use */
#ifdef __LP64__
uint64_t reserved[12];
#else
uint32_t reserved[12];
#endif

/** Close this device */
int (*close)(struct hw_device_t* device);

} hw_device_t;

#ifdef __cplusplus
#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast<struct hw_device_t**>(x)
#else
#define TO_HW_DEVICE_T_OPEN(x) (struct hw_device_t**)(x)
#endif

/**
* Name of the hal_module_info
*/
#define HAL_MODULE_INFO_SYM HMI

/**
* Name of the hal_module_info as a string
*/
#define HAL_MODULE_INFO_SYM_AS_STR "HMI"

/**
* Get the module info associated with a module by id.
*
* @return: 0 == success, <0 == error and *module == NULL
*/
int hw_get_module(const char *id, const struct hw_module_t **module);

/**
* Get the module info associated with a module instance by class 'class_id'
* and instance 'inst'.
*
* Some modules types necessitate multiple instances. For example audio supports
* multiple concurrent interfaces and thus 'audio' is the module class
* and 'primary' or 'a2dp' are module interfaces. This implies that the files
* providing these modules would be named audio.primary.<variant>.so and
* audio.a2dp.<variant>.so
*
* @return: 0 == success, <0 == error and *module == NULL
*/
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module);

__END_DECLS

#endif /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */

从上面的定义可以看出,主要是通过hw_module_t 代表了模块,通过其open方法用来打开一个设备,而该设备是用hw_device_t来表示,其中除了用来关闭设备的close方法外,并无其它方法,由此可见谷歌定义的HAL接口,并不能满足绝大部分HAL模块的需要,所以谷歌想出了一个比较好的解决方式,那便是将这两个基本结构嵌入到更大的结构体内部,同时在更大的结构内部定义了各自模块特有的方法,用于实现模块的功能,这样,一来对上保持了HAL的统一规范,二来也扩展了模块的功能。

基于上面的方式,谷歌便针对Camera 提出了HAL3接口,其中主要包括了用于代表一系列操作主体的结构体以及具体操作函数,接下来我们分别进行详细介绍:

HAL3中主要定义了camera_module_t/camera3_device_t/camera3_stream_configuration/camera3_stream以及camera3_stream_buffer几个主要结构体。

4.1 camera_module_t

[->/hardware/libhardware/include/hardware/camera_common.h]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
typedef struct camera_module {
/**
* Common methods of the camera module. This *must* be the first member of
* camera_module as users of this structure will cast a hw_module_t to
* camera_module pointer in contexts where it's known the hw_module_t
* references a camera_module.
*
* The return values for common.methods->open for camera_module are:
*
* 0: On a successful open of the camera device.
*
* -ENODEV: The camera device cannot be opened due to an internal
* error.
*
* -EINVAL: The input arguments are invalid, i.e. the id is invalid,
* and/or the module is invalid.
*
* -EBUSY: The camera device was already opened for this camera id
* (by using this method or open_legacy),
* regardless of the device HAL version it was opened as.
*
* -EUSERS: The maximal number of camera devices that can be
* opened concurrently were opened already, either by
* this method or the open_legacy method.
*
* All other return values from common.methods->open will be treated as
* -ENODEV.
*/
hw_module_t common;

/**
* get_number_of_cameras:
*
* Returns the number of camera devices accessible through the camera
* module. The camera devices are numbered 0 through N-1, where N is the
* value returned by this call. The name of the camera device for open() is
* simply the number converted to a string. That is, "0" for camera ID 0,
* "1" for camera ID 1.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_2_3 or lower:
*
* The value here must be static, and cannot change after the first call
* to this method.
*
* CAMERA_MODULE_API_VERSION_2_4 or higher:
*
* The value here must be static, and must count only built-in cameras,
* which have CAMERA_FACING_BACK or CAMERA_FACING_FRONT camera facing values
* (camera_info.facing). The HAL must not include the external cameras
* (camera_info.facing == CAMERA_FACING_EXTERNAL) into the return value
* of this call. Frameworks will use camera_device_status_change callback
* to manage number of external cameras.
*/
int (*get_number_of_cameras)(void);

/**
* get_camera_info:
*
* Return the static camera information for a given camera device. This
* information may not change for a camera device.
*
* Return values:
*
* 0: On a successful operation
*
* -ENODEV: The information cannot be provided due to an internal
* error.
*
* -EINVAL: The input arguments are invalid, i.e. the id is invalid,
* and/or the module is invalid.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_2_4 or higher:
*
* When a camera is disconnected, its camera id becomes invalid. Calling this
* this method with this invalid camera id will get -EINVAL and NULL camera
* static metadata (camera_info.static_camera_characteristics).
*/
int (*get_camera_info)(int camera_id, struct camera_info *info);

/**
* set_callbacks:
*
* Provide callback function pointers to the HAL module to inform framework
* of asynchronous camera module events. The framework will call this
* function once after initial camera HAL module load, after the
* get_number_of_cameras() method is called for the first time, and before
* any other calls to the module.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_0, CAMERA_MODULE_API_VERSION_2_0:
*
* Not provided by HAL module. Framework may not call this function.
*
* CAMERA_MODULE_API_VERSION_2_1:
*
* Valid to be called by the framework.
*
* Return values:
*
* 0: On a successful operation
*
* -ENODEV: The operation cannot be completed due to an internal
* error.
*
* -EINVAL: The input arguments are invalid, i.e. the callbacks are
* null
*/
int (*set_callbacks)(const camera_module_callbacks_t *callbacks);

/**
* get_vendor_tag_ops:
*
* Get methods to query for vendor extension metadata tag information. The
* HAL should fill in all the vendor tag operation methods, or leave ops
* unchanged if no vendor tags are defined.
*
* The vendor_tag_ops structure used here is defined in:
* system/media/camera/include/system/vendor_tags.h
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_x/2_0/2_1:
* Not provided by HAL module. Framework may not call this function.
*
* CAMERA_MODULE_API_VERSION_2_2:
* Valid to be called by the framework.
*/
void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);

/**
* open_legacy:
*
* Open a specific legacy camera HAL device if multiple device HAL API
* versions are supported by this camera HAL module. For example, if the
* camera module supports both CAMERA_DEVICE_API_VERSION_1_0 and
* CAMERA_DEVICE_API_VERSION_3_2 device API for the same camera id,
* framework can call this function to open the camera device as
* CAMERA_DEVICE_API_VERSION_1_0 device.
*
* This is an optional method. A Camera HAL module does not need to support
* more than one device HAL version per device, and such modules may return
* -ENOSYS for all calls to this method. For all older HAL device API
* versions that are not supported, it may return -EOPNOTSUPP. When above
* cases occur, The normal open() method (common.methods->open) will be
* used by the framework instead.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2:
* Not provided by HAL module. Framework will not call this function.
*
* CAMERA_MODULE_API_VERSION_2_3:
* Valid to be called by the framework.
*
* Return values:
*
* 0: On a successful open of the camera device.
*
* -ENOSYS This method is not supported.
*
* -EOPNOTSUPP: The requested HAL version is not supported by this method.
*
* -EINVAL: The input arguments are invalid, i.e. the id is invalid,
* and/or the module is invalid.
*
* -EBUSY: The camera device was already opened for this camera id
* (by using this method or common.methods->open method),
* regardless of the device HAL version it was opened as.
*
* -EUSERS: The maximal number of camera devices that can be
* opened concurrently were opened already, either by
* this method or common.methods->open method.
*/
int (*open_legacy)(const struct hw_module_t* module, const char* id,
uint32_t halVersion, struct hw_device_t** device);

/**
* set_torch_mode:
*
* Turn on or off the torch mode of the flash unit associated with a given
* camera ID. If the operation is successful, HAL must notify the framework
* torch state by invoking
* camera_module_callbacks.torch_mode_status_change() with the new state.
*
* The camera device has a higher priority accessing the flash unit. When
* there are any resource conflicts, such as open() is called to open a
* camera device, HAL module must notify the framework through
* camera_module_callbacks.torch_mode_status_change() that the
* torch mode has been turned off and the torch mode state has become
* TORCH_MODE_STATUS_NOT_AVAILABLE. When resources to turn on torch mode
* become available again, HAL module must notify the framework through
* camera_module_callbacks.torch_mode_status_change() that the torch mode
* state has become TORCH_MODE_STATUS_AVAILABLE_OFF for set_torch_mode() to
* be called.
*
* When the framework calls set_torch_mode() to turn on the torch mode of a
* flash unit, if HAL cannot keep multiple torch modes on simultaneously,
* HAL should turn off the torch mode that was turned on by
* a previous set_torch_mode() call and notify the framework that the torch
* mode state of that flash unit has become TORCH_MODE_STATUS_AVAILABLE_OFF.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3:
* Not provided by HAL module. Framework will not call this function.
*
* CAMERA_MODULE_API_VERSION_2_4:
* Valid to be called by the framework.
*
* Return values:
*
* 0: On a successful operation.
*
* -ENOSYS: The camera device does not support this operation. It is
* returned if and only if android.flash.info.available is
* false.
*
* -EBUSY: The camera device is already in use.
*
* -EUSERS: The resources needed to turn on the torch mode are not
* available, typically because other camera devices are
* holding the resources to make using the flash unit not
* possible.
*
* -EINVAL: camera_id is invalid.
*
*/
int (*set_torch_mode)(const char* camera_id, bool enabled);

/**
* init:
*
* This method is called by the camera service before any other methods
* are invoked, right after the camera HAL library has been successfully
* loaded. It may be left as NULL by the HAL module, if no initialization
* in needed.
*
* It can be used by HAL implementations to perform initialization and
* other one-time operations.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3:
* Not provided by HAL module. Framework will not call this function.
*
* CAMERA_MODULE_API_VERSION_2_4:
* If not NULL, will always be called by the framework once after the HAL
* module is loaded, before any other HAL module method is called.
*
* Return values:
*
* 0: On a successful operation.
*
* -ENODEV: Initialization cannot be completed due to an internal
* error. The HAL must be assumed to be in a nonfunctional
* state.
*
*/
int (*init)();

/**
* get_physical_camera_info:
*
* Return the static metadata for a physical camera as a part of a logical
* camera device. This function is only called for those physical camera
* ID(s) that are not exposed independently. In other words, camera_id will
* be greater or equal to the return value of get_number_of_cameras().
*
* Return values:
*
* 0: On a successful operation
*
* -ENODEV: The information cannot be provided due to an internal
* error.
*
* -EINVAL: The input arguments are invalid, i.e. the id is invalid,
* and/or the module is invalid.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3/2_4:
* Not provided by HAL module. Framework will not call this function.
*
* CAMERA_MODULE_API_VERSION_2_5 or higher:
* If any of the camera devices accessible through this camera module is
* a logical multi-camera, and at least one of the physical cameras isn't
* a stand-alone camera device, this function will be called by the camera
* framework. Calling this function with invalid physical_camera_id will
* get -EINVAL, and NULL static_metadata.
*/
int (*get_physical_camera_info)(int physical_camera_id,
camera_metadata_t **static_metadata);

/**
* is_stream_combination_supported:
*
* Check for device support of specific camera stream combination.
*
* Return values:
*
* 0: In case the stream combination is supported.
*
* -EINVAL: In case the stream combination is not supported.
*
* -ENOSYS: In case stream combination query is not supported.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3/2_4:
* Not provided by HAL module. Framework will not call this function.
*
* CAMERA_MODULE_API_VERSION_2_5 or higher:
* Valid to be called by the framework.
*/
int (*is_stream_combination_supported)(int camera_id,
const camera_stream_combination_t *streams);

/**
* notify_device_state_change:
*
* Notify the camera module that the state of the overall device has
* changed in some way that the HAL may want to know about.
*
* For example, a physical shutter may have been uncovered or covered,
* or a camera may have been covered or uncovered by an add-on keyboard
* or other accessory.
*
* The state is a bitfield of potential states, and some physical configurations
* could plausibly correspond to multiple different combinations of state bits.
* The HAL must ignore any state bits it is not actively using to determine
* the appropriate camera configuration.
*
* For example, on some devices the FOLDED state could mean that
* backward-facing cameras are covered by the fold, so FOLDED by itself implies
* BACK_COVERED. But other devices may support folding but not cover any cameras
* when folded, so for those FOLDED would not imply any of the other flags.
* Since these relationships are very device-specific, it is difficult to specify
* a comprehensive policy. But as a recommendation, it is suggested that if a flag
* necessarily implies other flags are set as well, then those flags should be set.
* So even though FOLDED would be enough to infer BACK_COVERED on some devices, the
* BACK_COVERED flag should also be set for clarity.
*
* This method may be invoked by the HAL client at any time. It must not
* cause any active camera device sessions to be closed, but may dynamically
* change which physical camera a logical multi-camera is using for its
* active and future output.
*
* The method must be invoked by the HAL client at least once before the
* client calls ICameraDevice::open on any camera device interfaces listed
* by this provider, to establish the initial device state.
*
* Note that the deviceState is 64-bit bitmask, with system defined states in
* lower 32-bit and vendor defined states in upper 32-bit.
*/
void (*notify_device_state_change)(uint64_t deviceState);

/**
* get_camera_device_version:
*
* Return the device version for a given camera device. This value may not change for a camera
* device. The version returned here must be the same as the one from get_camera_info.
*
* Return values:
*
* 0: On a successful operation
*
* -ENODEV: The information cannot be provided due to an internal
* error.
*
* -EINVAL: The input arguments are invalid, i.e. the id is invalid,
* and/or the module is invalid.
*
* Version information (based on camera_module_t.common.module_api_version):
*
* CAMERA_MODULE_API_VERSION_2_5 or higher:
*
* When a camera is disconnected, its camera id becomes invalid. Calling this
* this method with this invalid camera id will get -EINVAL and NULL camera
* static metadata (camera_info.static_camera_characteristics).
*/
int (*get_camera_device_version)(int camera_id, uint32_t *version);

/* reserved for future use */
void* reserved[1];
} camera_module_t;

camera_module_t包含了hw_module_t,主要用于表示Camera模块,其中定义了诸如get_number_of_cameras以及set_callbacks等扩展方法

4.2 camera3_device_t

[->hardware/libhardware/include/hardware/camera3.h]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef struct camera3_device {
/**
* common.version must equal CAMERA_DEVICE_API_VERSION_3_0 to identify this
* device as implementing version 3.0 of the camera device HAL.
*
* Performance requirements:
*
* Camera open (common.module->common.methods->open) should return in 200ms, and must return
* in 500ms.
* Camera close (common.close) should return in 200ms, and must return in 500ms.
*
*/
hw_device_t common;
camera3_device_ops_t *ops;
void *priv;
} camera3_device_t;

camera3_device_t包含了hw_device_t,主要用来表示Camera设备,其中定义了camera3_device_ops操作方法集合,用来实现正常获取图像数据以及控制Camera的功能。

4.3 camera3_device_ops

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
typedef struct camera3_device_ops {

/**
* initialize:
*
* One-time initialization to pass framework callback function pointers to
* the HAL. Will be called once after a successful open() call, before any
* other functions are called on the camera3_device_ops structure.
*
* Performance requirements:
*
* This should be a non-blocking call. The HAL should return from this call
* in 5ms, and must return from this call in 10ms.
*
* Return values:
*
* 0: On successful initialization
*
* -ENODEV: If initialization fails. Only close() can be called successfully
* by the framework after this.
*/
int (*initialize)(const struct camera3_device *,
const camera3_callback_ops_t *callback_ops);

/**********************************************************************
* Stream management
*/

/**
* configure_streams:
*
* CAMERA_DEVICE_API_VERSION_3_0 only:
*
* Reset the HAL camera device processing pipeline and set up new input and
* output streams. This call replaces any existing stream configuration with
* the streams defined in the stream_list. This method will be called at
* least once after initialize() before a request is submitted with
* process_capture_request().
*
* The stream_list must contain at least one output-capable stream, and may
* not contain more than one input-capable stream.
*
* The stream_list may contain streams that are also in the currently-active
* set of streams (from the previous call to configure_stream()). These
* streams will already have valid values for usage, max_buffers, and the
* private pointer.
*
* If such a stream has already had its buffers registered,
* register_stream_buffers() will not be called again for the stream, and
* buffers from the stream can be immediately included in input requests.
*
* If the HAL needs to change the stream configuration for an existing
* stream due to the new configuration, it may rewrite the values of usage
* and/or max_buffers during the configure call.
*
* The framework will detect such a change, and will then reallocate the
* stream buffers, and call register_stream_buffers() again before using
* buffers from that stream in a request.
*
* If a currently-active stream is not included in stream_list, the HAL may
* safely remove any references to that stream. It will not be reused in a
* later configure() call by the framework, and all the gralloc buffers for
* it will be freed after the configure_streams() call returns.
*
* The stream_list structure is owned by the framework, and may not be
* accessed once this call completes. The address of an individual
* camera3_stream_t structure will remain valid for access by the HAL until
* the end of the first configure_stream() call which no longer includes
* that camera3_stream_t in the stream_list argument. The HAL may not change
* values in the stream structure outside of the private pointer, except for
* the usage and max_buffers members during the configure_streams() call
* itself.
*
* If the stream is new, the usage, max_buffer, and private pointer fields
* of the stream structure will all be set to 0. The HAL device must set
* these fields before the configure_streams() call returns. These fields
* are then used by the framework and the platform gralloc module to
* allocate the gralloc buffers for each stream.
*
* Before such a new stream can have its buffers included in a capture
* request, the framework will call register_stream_buffers() with that
* stream. However, the framework is not required to register buffers for
* _all_ streams before submitting a request. This allows for quick startup
* of (for example) a preview stream, with allocation for other streams
* happening later or concurrently.
*
* ------------------------------------------------------------------------
* CAMERA_DEVICE_API_VERSION_3_1 only:
*
* Reset the HAL camera device processing pipeline and set up new input and
* output streams. This call replaces any existing stream configuration with
* the streams defined in the stream_list. This method will be called at
* least once after initialize() before a request is submitted with
* process_capture_request().
*
* The stream_list must contain at least one output-capable stream, and may
* not contain more than one input-capable stream.
*
* The stream_list may contain streams that are also in the currently-active
* set of streams (from the previous call to configure_stream()). These
* streams will already have valid values for usage, max_buffers, and the
* private pointer.
*
* If such a stream has already had its buffers registered,
* register_stream_buffers() will not be called again for the stream, and
* buffers from the stream can be immediately included in input requests.
*
* If the HAL needs to change the stream configuration for an existing
* stream due to the new configuration, it may rewrite the values of usage
* and/or max_buffers during the configure call.
*
* The framework will detect such a change, and will then reallocate the
* stream buffers, and call register_stream_buffers() again before using
* buffers from that stream in a request.
*
* If a currently-active stream is not included in stream_list, the HAL may
* safely remove any references to that stream. It will not be reused in a
* later configure() call by the framework, and all the gralloc buffers for
* it will be freed after the configure_streams() call returns.
*
* The stream_list structure is owned by the framework, and may not be
* accessed once this call completes. The address of an individual
* camera3_stream_t structure will remain valid for access by the HAL until
* the end of the first configure_stream() call which no longer includes
* that camera3_stream_t in the stream_list argument. The HAL may not change
* values in the stream structure outside of the private pointer, except for
* the usage and max_buffers members during the configure_streams() call
* itself.
*
* If the stream is new, max_buffer, and private pointer fields of the
* stream structure will all be set to 0. The usage will be set to the
* consumer usage flags. The HAL device must set these fields before the
* configure_streams() call returns. These fields are then used by the
* framework and the platform gralloc module to allocate the gralloc
* buffers for each stream.
*
* Before such a new stream can have its buffers included in a capture
* request, the framework will call register_stream_buffers() with that
* stream. However, the framework is not required to register buffers for
* _all_ streams before submitting a request. This allows for quick startup
* of (for example) a preview stream, with allocation for other streams
* happening later or concurrently.
*
* ------------------------------------------------------------------------
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* Reset the HAL camera device processing pipeline and set up new input and
* output streams. This call replaces any existing stream configuration with
* the streams defined in the stream_list. This method will be called at
* least once after initialize() before a request is submitted with
* process_capture_request().
*
* The stream_list must contain at least one output-capable stream, and may
* not contain more than one input-capable stream.
*
* The stream_list may contain streams that are also in the currently-active
* set of streams (from the previous call to configure_stream()). These
* streams will already have valid values for usage, max_buffers, and the
* private pointer.
*
* If the HAL needs to change the stream configuration for an existing
* stream due to the new configuration, it may rewrite the values of usage
* and/or max_buffers during the configure call.
*
* The framework will detect such a change, and may then reallocate the
* stream buffers before using buffers from that stream in a request.
*
* If a currently-active stream is not included in stream_list, the HAL may
* safely remove any references to that stream. It will not be reused in a
* later configure() call by the framework, and all the gralloc buffers for
* it will be freed after the configure_streams() call returns.
*
* The stream_list structure is owned by the framework, and may not be
* accessed once this call completes. The address of an individual
* camera3_stream_t structure will remain valid for access by the HAL until
* the end of the first configure_stream() call which no longer includes
* that camera3_stream_t in the stream_list argument. The HAL may not change
* values in the stream structure outside of the private pointer, except for
* the usage and max_buffers members during the configure_streams() call
* itself.
*
* If the stream is new, max_buffer, and private pointer fields of the
* stream structure will all be set to 0. The usage will be set to the
* consumer usage flags. The HAL device must set these fields before the
* configure_streams() call returns. These fields are then used by the
* framework and the platform gralloc module to allocate the gralloc
* buffers for each stream.
*
* Newly allocated buffers may be included in a capture request at any time
* by the framework. Once a gralloc buffer is returned to the framework
* with process_capture_result (and its respective release_fence has been
* signaled) the framework may free or reuse it at any time.
*
* ------------------------------------------------------------------------
*
* Preconditions:
*
* The framework will only call this method when no captures are being
* processed. That is, all results have been returned to the framework, and
* all in-flight input and output buffers have been returned and their
* release sync fences have been signaled by the HAL. The framework will not
* submit new requests for capture while the configure_streams() call is
* underway.
*
* Postconditions:
*
* The HAL device must configure itself to provide maximum possible output
* frame rate given the sizes and formats of the output streams, as
* documented in the camera device's static metadata.
*
* Performance requirements:
*
* This call is expected to be heavyweight and possibly take several hundred
* milliseconds to complete, since it may require resetting and
* reconfiguring the image sensor and the camera processing pipeline.
* Nevertheless, the HAL device should attempt to minimize the
* reconfiguration delay to minimize the user-visible pauses during
* application operational mode changes (such as switching from still
* capture to video recording).
*
* The HAL should return from this call in 500ms, and must return from this
* call in 1000ms.
*
* Return values:
*
* 0: On successful stream configuration
*
* -EINVAL: If the requested stream configuration is invalid. Some examples
* of invalid stream configurations include:
*
* - Including more than 1 input-capable stream (INPUT or
* BIDIRECTIONAL)
*
* - Not including any output-capable streams (OUTPUT or
* BIDIRECTIONAL)
*
* - Including streams with unsupported formats, or an unsupported
* size for that format.
*
* - Including too many output streams of a certain format.
*
* - Unsupported rotation configuration (only applies to
* devices with version >= CAMERA_DEVICE_API_VERSION_3_3)
*
* - Stream sizes/formats don't satisfy the
* camera3_stream_configuration_t->operation_mode requirements for non-NORMAL mode,
* or the requested operation_mode is not supported by the HAL.
* (only applies to devices with version >= CAMERA_DEVICE_API_VERSION_3_3)
*
* Note that the framework submitting an invalid stream
* configuration is not normal operation, since stream
* configurations are checked before configure. An invalid
* configuration means that a bug exists in the framework code, or
* there is a mismatch between the HAL's static metadata and the
* requirements on streams.
*
* -ENODEV: If there has been a fatal error and the device is no longer
* operational. Only close() can be called successfully by the
* framework after this error is returned.
*/
int (*configure_streams)(const struct camera3_device *,
camera3_stream_configuration_t *stream_list);

/**
* register_stream_buffers:
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* DEPRECATED. This will not be called and must be set to NULL.
*
* <= CAMERA_DEVICE_API_VERSION_3_1:
*
* Register buffers for a given stream with the HAL device. This method is
* called by the framework after a new stream is defined by
* configure_streams, and before buffers from that stream are included in a
* capture request. If the same stream is listed in a subsequent
* configure_streams() call, register_stream_buffers will _not_ be called
* again for that stream.
*
* The framework does not need to register buffers for all configured
* streams before it submits the first capture request. This allows quick
* startup for preview (or similar use cases) while other streams are still
* being allocated.
*
* This method is intended to allow the HAL device to map or otherwise
* prepare the buffers for later use. The buffers passed in will already be
* locked for use. At the end of the call, all the buffers must be ready to
* be returned to the stream. The buffer_set argument is only valid for the
* duration of this call.
*
* If the stream format was set to HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
* the camera HAL should inspect the passed-in buffers here to determine any
* platform-private pixel format information.
*
* Performance requirements:
*
* This should be a non-blocking call. The HAL should return from this call
* in 1ms, and must return from this call in 5ms.
*
* Return values:
*
* 0: On successful registration of the new stream buffers
*
* -EINVAL: If the stream_buffer_set does not refer to a valid active
* stream, or if the buffers array is invalid.
*
* -ENOMEM: If there was a failure in registering the buffers. The framework
* must consider all the stream buffers to be unregistered, and can
* try to register again later.
*
* -ENODEV: If there is a fatal error, and the device is no longer
* operational. Only close() can be called successfully by the
* framework after this error is returned.
*/
int (*register_stream_buffers)(const struct camera3_device *,
const camera3_stream_buffer_set_t *buffer_set);

/**********************************************************************
* Request creation and submission
*/

/**
* construct_default_request_settings:
*
* Create capture settings for standard camera use cases.
*
* The device must return a settings buffer that is configured to meet the
* requested use case, which must be one of the CAMERA3_TEMPLATE_*
* enums. All request control fields must be included.
*
* The HAL retains ownership of this structure, but the pointer to the
* structure must be valid until the device is closed. The framework and the
* HAL may not modify the buffer once it is returned by this call. The same
* buffer may be returned for subsequent calls for the same template, or for
* other templates.
*
* Performance requirements:
*
* This should be a non-blocking call. The HAL should return from this call
* in 1ms, and must return from this call in 5ms.
*
* Return values:
*
* Valid metadata: On successful creation of a default settings
* buffer.
*
* NULL: In case of a fatal error. After this is returned, only
* the close() method can be called successfully by the
* framework.
*/
const camera_metadata_t* (*construct_default_request_settings)(
const struct camera3_device *,
int type);

/**
* process_capture_request:
*
* Send a new capture request to the HAL. The HAL should not return from
* this call until it is ready to accept the next request to process. Only
* one call to process_capture_request() will be made at a time by the
* framework, and the calls will all be from the same thread. The next call
* to process_capture_request() will be made as soon as a new request and
* its associated buffers are available. In a normal preview scenario, this
* means the function will be called again by the framework almost
* instantly.
*
* The actual request processing is asynchronous, with the results of
* capture being returned by the HAL through the process_capture_result()
* call. This call requires the result metadata to be available, but output
* buffers may simply provide sync fences to wait on. Multiple requests are
* expected to be in flight at once, to maintain full output frame rate.
*
* The framework retains ownership of the request structure. It is only
* guaranteed to be valid during this call. The HAL device must make copies
* of the information it needs to retain for the capture processing. The HAL
* is responsible for waiting on and closing the buffers' fences and
* returning the buffer handles to the framework.
*
* The HAL must write the file descriptor for the input buffer's release
* sync fence into input_buffer->release_fence, if input_buffer is not
* NULL. If the HAL returns -1 for the input buffer release sync fence, the
* framework is free to immediately reuse the input buffer. Otherwise, the
* framework will wait on the sync fence before refilling and reusing the
* input buffer.
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* The input/output buffers provided by the framework in each request
* may be brand new (having never before seen by the HAL).
*
* ------------------------------------------------------------------------
* Performance considerations:
*
* Handling a new buffer should be extremely lightweight and there should be
* no frame rate degradation or frame jitter introduced.
*
* This call must return fast enough to ensure that the requested frame
* rate can be sustained, especially for streaming cases (post-processing
* quality settings set to FAST). The HAL should return this call in 1
* frame interval, and must return from this call in 4 frame intervals.
*
* Return values:
*
* 0: On a successful start to processing the capture request
*
* -EINVAL: If the input is malformed (the settings are NULL when not
* allowed, invalid physical camera settings,
* there are 0 output buffers, etc) and capture processing
* cannot start. Failures during request processing should be
* handled by calling camera3_callback_ops_t.notify(). In case of
* this error, the framework will retain responsibility for the
* stream buffers' fences and the buffer handles; the HAL should
* not close the fences or return these buffers with
* process_capture_result.
*
* -ENODEV: If the camera device has encountered a serious error. After this
* error is returned, only the close() method can be successfully
* called by the framework.
*
*/
int (*process_capture_request)(const struct camera3_device *,
camera3_capture_request_t *request);

/**********************************************************************
* Miscellaneous methods
*/

/**
* get_metadata_vendor_tag_ops:
*
* Get methods to query for vendor extension metadata tag information. The
* HAL should fill in all the vendor tag operation methods, or leave ops
* unchanged if no vendor tags are defined.
*
* The definition of vendor_tag_query_ops_t can be found in
* system/media/camera/include/system/camera_metadata.h.
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
* DEPRECATED. This function has been deprecated and should be set to
* NULL by the HAL. Please implement get_vendor_tag_ops in camera_common.h
* instead.
*/
void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,
vendor_tag_query_ops_t* ops);

/**
* dump:
*
* Print out debugging state for the camera device. This will be called by
* the framework when the camera service is asked for a debug dump, which
* happens when using the dumpsys tool, or when capturing a bugreport.
*
* The passed-in file descriptor can be used to write debugging text using
* dprintf() or write(). The text should be in ASCII encoding only.
*
* Performance requirements:
*
* This must be a non-blocking call. The HAL should return from this call
* in 1ms, must return from this call in 10ms. This call must avoid
* deadlocks, as it may be called at any point during camera operation.
* Any synchronization primitives used (such as mutex locks or semaphores)
* should be acquired with a timeout.
*/
void (*dump)(const struct camera3_device *, int fd);

/**
* flush:
*
* Flush all currently in-process captures and all buffers in the pipeline
* on the given device. The framework will use this to dump all state as
* quickly as possible in order to prepare for a configure_streams() call.
*
* No buffers are required to be successfully returned, so every buffer
* held at the time of flush() (whether successfully filled or not) may be
* returned with CAMERA3_BUFFER_STATUS_ERROR. Note the HAL is still allowed
* to return valid (CAMERA3_BUFFER_STATUS_OK) buffers during this call,
* provided they are successfully filled.
*
* All requests currently in the HAL are expected to be returned as soon as
* possible. Not-in-process requests should return errors immediately. Any
* interruptible hardware blocks should be stopped, and any uninterruptible
* blocks should be waited on.
*
* flush() may be called concurrently to process_capture_request(), with the expectation that
* process_capture_request will return quickly and the request submitted in that
* process_capture_request call is treated like all other in-flight requests. Due to
* concurrency issues, it is possible that from the HAL's point of view, a
* process_capture_request() call may be started after flush has been invoked but has not
* returned yet. If such a call happens before flush() returns, the HAL should treat the new
* capture request like other in-flight pending requests (see #4 below).
*
* More specifically, the HAL must follow below requirements for various cases:
*
* 1. For captures that are too late for the HAL to cancel/stop, and will be
* completed normally by the HAL; i.e. the HAL can send shutter/notify and
* process_capture_result and buffers as normal.
*
* 2. For pending requests that have not done any processing, the HAL must call notify
* CAMERA3_MSG_ERROR_REQUEST, and return all the output buffers with
* process_capture_result in the error state (CAMERA3_BUFFER_STATUS_ERROR).
* The HAL must not place the release fence into an error state, instead,
* the release fences must be set to the acquire fences passed by the framework,
* or -1 if they have been waited on by the HAL already. This is also the path
* to follow for any captures for which the HAL already called notify() with
* CAMERA3_MSG_SHUTTER but won't be producing any metadata/valid buffers for.
* After CAMERA3_MSG_ERROR_REQUEST, for a given frame, only process_capture_results with
* buffers in CAMERA3_BUFFER_STATUS_ERROR are allowed. No further notifys or
* process_capture_result with non-null metadata is allowed.
*
* 3. For partially completed pending requests that will not have all the output
* buffers or perhaps missing metadata, the HAL should follow below:
*
* 3.1. Call notify with CAMERA3_MSG_ERROR_RESULT if some of the expected result
* metadata (i.e. one or more partial metadata) won't be available for the capture.
*
* 3.2. Call notify with CAMERA3_MSG_ERROR_BUFFER for every buffer that won't
* be produced for the capture.
*
* 3.3 Call notify with CAMERA3_MSG_SHUTTER with the capture timestamp before
* any buffers/metadata are returned with process_capture_result.
*
* 3.4 For captures that will produce some results, the HAL must not call
* CAMERA3_MSG_ERROR_REQUEST, since that indicates complete failure.
*
* 3.5. Valid buffers/metadata should be passed to the framework as normal.
*
* 3.6. Failed buffers should be returned to the framework as described for case 2.
* But failed buffers do not have to follow the strict ordering valid buffers do,
* and may be out-of-order with respect to valid buffers. For example, if buffers
* A, B, C, D, E are sent, D and E are failed, then A, E, B, D, C is an acceptable
* return order.
*
* 3.7. For fully-missing metadata, calling CAMERA3_MSG_ERROR_RESULT is sufficient, no
* need to call process_capture_result with NULL metadata or equivalent.
*
* 4. If a flush() is invoked while a process_capture_request() invocation is active, that
* process call should return as soon as possible. In addition, if a process_capture_request()
* call is made after flush() has been invoked but before flush() has returned, the
* capture request provided by the late process_capture_request call should be treated like
* a pending request in case #2 above.
*
* flush() should only return when there are no more outstanding buffers or
* requests left in the HAL. The framework may call configure_streams (as
* the HAL state is now quiesced) or may issue new requests.
*
* Note that it's sufficient to only support fully-succeeded and fully-failed result cases.
* However, it is highly desirable to support the partial failure cases as well, as it
* could help improve the flush call overall performance.
*
* Performance requirements:
*
* The HAL should return from this call in 100ms, and must return from this
* call in 1000ms. And this call must not be blocked longer than pipeline
* latency (see S7 for definition).
*
* Version information:
*
* only available if device version >= CAMERA_DEVICE_API_VERSION_3_1.
*
* Return values:
*
* 0: On a successful flush of the camera HAL.
*
* -EINVAL: If the input is malformed (the device is not valid).
*
* -ENODEV: If the camera device has encountered a serious error. After this
* error is returned, only the close() method can be successfully
* called by the framework.
*/
int (*flush)(const struct camera3_device *);

/**
* signal_stream_flush:
*
* <= CAMERA_DEVICE_API_VERISON_3_5:
*
* Not defined and must be NULL
*
* >= CAMERA_DEVICE_API_VERISON_3_6:
*
* Signaling HAL camera service is about to perform configure_streams() call
* and HAL must return all buffers of designated streams. HAL must finish
* inflight requests normally and return all buffers belonging to the
* designated streams through process_capture_result() or
* return_stream_buffers() API in a timely manner, or camera service will run
* into a fatal error.
*
* Note that this call serves as an optional hint and camera service may
* skip calling this if all buffers are already returned.
*
*/
void (*signal_stream_flush)(const struct camera3_device*,
uint32_t num_streams,
const camera3_stream_t* const* streams);

/**
* is_reconfiguration_required:
*
* <= CAMERA_DEVICE_API_VERISON_3_5:
*
* Not defined and must be NULL
*
* >= CAMERA_DEVICE_API_VERISON_3_6:
*
* Check whether complete stream reconfiguration is required for possible new session
* parameter values.
*
* This method must be called by the camera framework in case the client changes
* the value of any advertised session parameters. Depending on the specific values
* the HAL can decide whether a complete stream reconfiguration is required. In case
* the HAL returns -ENVAL, the camera framework must skip the internal reconfiguration.
* In case Hal returns 0, the framework must reconfigure the streams and pass the
* new session parameter values accordingly.
* This call may be done by the framework some time before the request with new parameters
* is submitted to the HAL, and the request may be cancelled before it ever gets submitted.
* Therefore, the HAL must not use this query as an indication to change its behavior in any
* way.
* ------------------------------------------------------------------------
*
* Preconditions:
*
* The framework can call this method at any time after active
* session configuration. There must be no impact on the performance of
* pending camera requests in any way. In particular there must not be
* any glitches or delays during normal camera streaming.
*
* Performance requirements:
* HW and SW camera settings must not be changed and there must not be
* a user-visible impact on camera performance.
*
* @param oldSessionParams The currently applied session parameters.
* @param newSessionParams The new session parameters set by client.
*
* @return Status Status code for the operation, one of:
* 0: In case the stream reconfiguration is required
*
* -EINVAL: In case the stream reconfiguration is not required.
*
* -ENOSYS: In case the camera device does not support the
* reconfiguration query.
*/
int (*is_reconfiguration_required)(const struct camera3_device*,
const camera_metadata_t* old_session_params,
const camera_metadata_t* new_session_params);

/* reserved for future use */
void *reserved[6];
} camera3_device_ops_t;

HAL3的核心接口都是在camera3_device_ops中被定义,从代码中可以看见,该结构体定义了一系列的函数指针,用来指向平台厂商实际的实现方法,接下来就其中几个方法简单介绍下:

a) initialize

该方法必须在camera_module_t中的open方法之后,其它camera3_device_ops中方法之前被调用,主要用来将上层实现的回调方法注册到HAL中,并且根据需要在该方法中加入自定义的一些初始化操作,另外,谷歌针对该方法在性能方面也有严格的限制,该方法需要在5ms内返回,最长不能超过10ms。

b) configure_streams

该方法在完成initialize方法之后,在调用process_capture_request方法之前被调用,主要用于重设当前正在运行的Pipeline以及设置新的输入输出流,其中它会将stream_list中的新的数据流替换之前配置的数据流。在调用该方法之前必须确保没有新的request下发并且当前request的动作已经完成,否则会引起无法预测的错误。一旦HAL调用了该方法,则必须在内部配置好满足当前数据流配置的帧率,确保这个流程的运行的顺畅性。

其中包含了两个参数,分别是camera3_device以及stream_list(camera3_stream_configuration_t ),其中第二个参数是上层传入的数据流配置列表,该列表中必须包含至少一个output stream,同时至多包含一个input stream。

另外,谷歌针对该方法有着严格的性能要求,平台厂商在实现该方法的时候,需要在500ms内返回,最长不能超过1000ms。

c) construct_default_request_settings

该方法主要用于构建一系列默认的Camera Usecase的capture 设置项,通过camera_metadata_t来进行描述,其中返回值是一个camera_metadata_t指针,其指向的内存地址是由HAL来进行维护的,同样地,该方法需要在1ms内返回,最长不能超过5ms。

d) process_capture_request

该方法用于下发单次新的capture request到HAL中, 上层必须保证该方法的调用都是在一个线程中完成,而且该方法是异步的,同时其结果并不是通过返回值给到上层,而是通过HAL调用另一个接口process_capture_result()来将结果返回给上层的,在使用的过程中,通过in-flight机制,保证短时间内下发足够多的request,从而满足帧率要求。

该方法的性能依然受到谷歌的严格要求,规定其需要在一帧图像处理完的时长内返回,最长不超过4帧图像处理完成的时长,比如当前预览帧率是30帧,则该方法的操作耗时最长不能超过120ms,否则便会引起明显的帧抖动,从而影响用户体验。

e) dump

该方法用于打印当前Camera设备的状态,一般是由上层通过dumpsys工具输出debug dump信息或者主动抓取bugreport的时候被调用,该方法必须是非阻塞实现,同时需要保证在1ms内返回,最长不能超过10ms。

f) flush

当上层需要执行新的configure_streams的时候,需要调用该方法去尽可能快地清除掉当前已经在处理中的或者即将处理的任务,为配置数据流提供一个相对稳定的环境,其具体工作如下:

  • 所有的还在流转的request会尽可能快的返回
  • 并未开始进行流转的request会直接返回,并携带错误信息
  • 任何可以打断的硬件操作会立即被停止
  • 任何无法进行打断的硬件操作会在当前状态下进行休眠
  • flush会在所有的buffer都得以释放,所有request都成功返回后才真正返回,该方法需要在100ms内返回,最长不能超过1000ms。

上面的一系列方法是上层直接对下控制Camera Hal,而一旦Camera Hal产生了数据或者事件的时候,可以通过camera3_callback_ops中定义的回调方法将数据或者事件返回至上层,其结构见下节。

4.4 camera3_callback_ops

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
typedef struct camera3_callback_ops {

/**
* process_capture_result:
*
* Send results from a completed capture to the framework.
* process_capture_result() may be invoked multiple times by the HAL in
* response to a single capture request. This allows, for example, the
* metadata and low-resolution buffers to be returned in one call, and
* post-processed JPEG buffers in a later call, once it is available. Each
* call must include the frame number of the request it is returning
* metadata or buffers for.
*
* A component (buffer or metadata) of the complete result may only be
* included in one process_capture_result call. A buffer for each stream,
* and the result metadata, must be returned by the HAL for each request in
* one of the process_capture_result calls, even in case of errors producing
* some of the output. A call to process_capture_result() with neither
* output buffers or result metadata is not allowed.
*
* The order of returning metadata and buffers for a single result does not
* matter, but buffers for a given stream must be returned in FIFO order. So
* the buffer for request 5 for stream A must always be returned before the
* buffer for request 6 for stream A. This also applies to the result
* metadata; the metadata for request 5 must be returned before the metadata
* for request 6.
*
* However, different streams are independent of each other, so it is
* acceptable and expected that the buffer for request 5 for stream A may be
* returned after the buffer for request 6 for stream B is. And it is
* acceptable that the result metadata for request 6 for stream B is
* returned before the buffer for request 5 for stream A is.
*
* The HAL retains ownership of result structure, which only needs to be
* valid to access during this call. The framework will copy whatever it
* needs before this call returns.
*
* The output buffers do not need to be filled yet; the framework will wait
* on the stream buffer release sync fence before reading the buffer
* data. Therefore, this method should be called by the HAL as soon as
* possible, even if some or all of the output buffers are still in
* being filled. The HAL must include valid release sync fences into each
* output_buffers stream buffer entry, or -1 if that stream buffer is
* already filled.
*
* If the result buffer cannot be constructed for a request, the HAL should
* return an empty metadata buffer, but still provide the output buffers and
* their sync fences. In addition, notify() must be called with an
* ERROR_RESULT message.
*
* If an output buffer cannot be filled, its status field must be set to
* STATUS_ERROR. In addition, notify() must be called with a ERROR_BUFFER
* message.
*
* If the entire capture has failed, then this method still needs to be
* called to return the output buffers to the framework. All the buffer
* statuses should be STATUS_ERROR, and the result metadata should be an
* empty buffer. In addition, notify() must be called with a ERROR_REQUEST
* message. In this case, individual ERROR_RESULT/ERROR_BUFFER messages
* should not be sent.
*
* Performance requirements:
*
* This is a non-blocking call. The framework will return this call in 5ms.
*
* The pipeline latency (see S7 for definition) should be less than or equal to
* 4 frame intervals, and must be less than or equal to 8 frame intervals.
*
*/
void (*process_capture_result)(const struct camera3_callback_ops *,
const camera3_capture_result_t *result);

/**
* notify:
*
* Asynchronous notification callback from the HAL, fired for various
* reasons. Only for information independent of frame capture, or that
* require specific timing. The ownership of the message structure remains
* with the HAL, and the msg only needs to be valid for the duration of this
* call.
*
* Multiple threads may call notify() simultaneously.
*
* <= CAMERA_DEVICE_API_VERSION_3_1:
*
* The notification for the start of exposure for a given request must be
* sent by the HAL before the first call to process_capture_result() for
* that request is made.
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* Buffers delivered to the framework will not be dispatched to the
* application layer until a start of exposure timestamp (or input image's
* start of exposure timestamp for a reprocess request) has been received
* via a SHUTTER notify() call. It is highly recommended to dispatch this
* call as early as possible.
*
* ------------------------------------------------------------------------
* Performance requirements:
*
* This is a non-blocking call. The framework will return this call in 5ms.
*/
void (*notify)(const struct camera3_callback_ops *,
const camera3_notify_msg_t *msg);

/**
* request_stream_buffers:
*
* <= CAMERA_DEVICE_API_VERISON_3_5:
*
* DO NOT USE: not defined and must be NULL.
*
* >= CAMERA_DEVICE_API_VERISON_3_6:
*
* Synchronous callback for HAL to ask for output buffer from camera service.
*
* This call may be serialized in camera service so it is strongly
* recommended to only call this method from one thread.
*
* When camera device advertises
* (android.info.supportedBufferManagementVersion ==
* ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5), HAL
* can use this method to request buffers from camera service.
*
* Caller is responsible for allocating enough memory for returned_buf_reqs
* argument (num_buffer_reqs * sizeof(camera3_stream_buffer_ret_t)) bytes
* and also the memory for the output_buffers field in each
* camera3_stream_buffer_ret_t
* (num_buffers_requested * sizeof(camera3_stream_buffer_t)) bytes
*
* Performance requirements:
* This is a blocking call that takes more time with more buffers requested.
* HAL should not request large amount of buffers on a latency critical code
* path. It is highly recommended to use a dedicated thread to perform
* all requestStreamBuffer calls, and adjust the thread priority and/or
* timing of making the call in order for buffers to arrive before HAL is
* ready to fill the buffer.
*/
camera3_buffer_request_status_t (*request_stream_buffers)(
const struct camera3_callback_ops *,
uint32_t num_buffer_reqs,
const camera3_buffer_request_t *buffer_reqs,
/*out*/uint32_t *num_returned_buf_reqs,
/*out*/camera3_stream_buffer_ret_t *returned_buf_reqs);

/**
* return_stream_buffers:
*
* <= CAMERA_DEVICE_API_VERISON_3_5:
*
* DO NOT USE: not defined and must be NULL.
*
* >= CAMERA_DEVICE_API_VERISON_3_6:
*
* Synchronous callback for HAL to return output buffers to camera service.
*
* If this method is called during a configure_streams() call, it will be
* blocked until camera service finishes the ongoing configure_streams() call.
*/
void (*return_stream_buffers)(
const struct camera3_callback_ops *,
uint32_t num_buffers,
const camera3_stream_buffer_t* const* buffers);

} camera3_callback_ops_t;

其中常用的回调方法主要有两个:用于返回数据的process_capture_result以及用于返回事件的notify,接下来分别介绍下:

a) process_capture_result

该方法用于返回HAL部分产生的metadata和image buffers,它与request是多对一的关系,同一个request,可能会对应到多个result,比如可以通过调用一次该方法用于返回metadata以及低分辨率的图像数据,再调用一次该方法用于返回jpeg格式的拍照数据,而这两次调用时对应于同一个process_capture_request动作。

同一个Request的Metadata以及Image Buffers的先后顺序无关紧要,但是同一个数据流的不同Request之间的Result必须严格按照Request的下发先后顺序进行依次返回的,如若不然,会导致图像数据显示出现顺序错乱的情况。

该方法是非阻塞的,而且并且必须要在5ms内返回。

b) notify

该方法用于异步返回HAL事件到上层,必须非阻塞实现,而且要在5ms内返回。

4.5 camera3_stream_configuration

[->hardware/libhardware/include/hardware/camera3.h]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* camera3_stream_configuration_t:
*
* A structure of stream definitions, used by configure_streams(). This
* structure defines all the output streams and the reprocessing input
* stream for the current camera use case.
*/
typedef struct camera3_stream_configuration {
/**
* The total number of streams requested by the framework. This includes
* both input and output streams. The number of streams will be at least 1,
* and there will be at least one output-capable stream.
*/
uint32_t num_streams;

/**
* An array of camera stream pointers, defining the input/output
* configuration for the camera HAL device.
*
* At most one input-capable stream may be defined (INPUT or BIDIRECTIONAL)
* in a single configuration.
*
* At least one output-capable stream must be defined (OUTPUT or
* BIDIRECTIONAL).
*/
camera3_stream_t **streams;

/**
* >= CAMERA_DEVICE_API_VERSION_3_3:
*
* The operation mode of streams in this configuration, one of the value
* defined in camera3_stream_configuration_mode_t. The HAL can use this
* mode as an indicator to set the stream property (e.g.,
* camera3_stream->max_buffers) appropriately. For example, if the
* configuration is
* CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE, the HAL may
* want to set aside more buffers for batch mode operation (see
* android.control.availableHighSpeedVideoConfigurations for batch mode
* definition).
*
*/
uint32_t operation_mode;

/**
* >= CAMERA_DEVICE_API_VERSION_3_5:
*
* The session metadata buffer contains the initial values of
* ANDROID_REQUEST_AVAILABLE_SESSION_KEYS. This field is optional
* and camera clients can choose to ignore it, in which case it will
* be set to NULL. If parameters are present, then Hal should examine
* the parameter values and configure its internal camera pipeline
* accordingly.
*/
const camera_metadata_t *session_parameters;
} camera3_stream_configuration_t;

该结构体主要用来代表配置的数据流列表,内部装有上层需要进行配置的数据流的指针,内部的定义简单介绍下:

  • num_streams: 代表了来自上层的数据流的数量,其中包括了output以及input stream。

  • streams: 是streams的指针数组,包括了至少一条output stream以及至多一条input stream。

  • operation_mode: 当前数据流的操作模式,该模式在camera3_stream_configuration_mode_t中被定义,HAL通过这个参数可以针对streams做不同的设置。

  • session_parameters: 该参数可以作为缺省参数,直接设置为NULL即可,CAMERA_DEVICE_API_VERSION_3_5以上的版本才支持。

4.6 camera3_stream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/**
* camera3_stream_t:
*
* A handle to a single camera input or output stream. A stream is defined by
* the framework by its buffer resolution and format, and additionally by the
* HAL with the gralloc usage flags and the maximum in-flight buffer count.
*
* The stream structures are owned by the framework, but pointers to a
* camera3_stream passed into the HAL by configure_streams() are valid until the
* end of the first subsequent configure_streams() call that _does not_ include
* that camera3_stream as an argument, or until the end of the close() call.
*
* All camera3_stream framework-controlled members are immutable once the
* camera3_stream is passed into configure_streams(). The HAL may only change
* the HAL-controlled parameters during a configure_streams() call, except for
* the contents of the private pointer.
*
* If a configure_streams() call returns a non-fatal error, all active streams
* remain valid as if configure_streams() had not been called.
*
* The endpoint of the stream is not visible to the camera HAL device.
* In DEVICE_API_VERSION_3_1, this was changed to share consumer usage flags
* on streams where the camera is a producer (OUTPUT and BIDIRECTIONAL stream
* types) see the usage field below.
*/
typedef struct camera3_stream {

/*****
* Set by framework before configure_streams()
*/

/**
* The type of the stream, one of the camera3_stream_type_t values.
*/
int stream_type;

/**
* The width in pixels of the buffers in this stream
*/
uint32_t width;

/**
* The height in pixels of the buffers in this stream
*/
uint32_t height;

/**
* The pixel format for the buffers in this stream. Format is a value from
* the HAL_PIXEL_FORMAT_* list in system/core/include/system/graphics.h, or
* from device-specific headers.
*
* If HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
* gralloc module will select a format based on the usage flags provided by
* the camera device and the other endpoint of the stream.
*
* <= CAMERA_DEVICE_API_VERSION_3_1:
*
* The camera HAL device must inspect the buffers handed to it in the
* subsequent register_stream_buffers() call to obtain the
* implementation-specific format details, if necessary.
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* register_stream_buffers() won't be called by the framework, so the HAL
* should configure the ISP and sensor pipeline based purely on the sizes,
* usage flags, and formats for the configured streams.
*/
int format;

/*****
* Set by HAL during configure_streams().
*/

/**
* The gralloc usage flags for this stream, as needed by the HAL. The usage
* flags are defined in gralloc.h (GRALLOC_USAGE_*), or in device-specific
* headers.
*
* For output streams, these are the HAL's producer usage flags. For input
* streams, these are the HAL's consumer usage flags. The usage flags from
* the producer and the consumer will be combined together and then passed
* to the platform gralloc HAL module for allocating the gralloc buffers for
* each stream.
*
* Version information:
*
* == CAMERA_DEVICE_API_VERSION_3_0:
*
* No initial value guaranteed when passed via configure_streams().
* HAL may not use this field as input, and must write over this field
* with its usage flags.
*
* >= CAMERA_DEVICE_API_VERSION_3_1:
*
* For stream_type OUTPUT and BIDIRECTIONAL, when passed via
* configure_streams(), the initial value of this is the consumer's
* usage flags. The HAL may use these consumer flags to decide stream
* configuration.
* For stream_type INPUT, when passed via configure_streams(), the initial
* value of this is 0.
* For all streams passed via configure_streams(), the HAL must write
* over this field with its usage flags.
*
* From Android O, the usage flag for an output stream may be bitwise
* combination of usage flags for multiple consumers, for the purpose of
* sharing one camera stream between those consumers. The HAL must fail
* configure_streams call with -EINVAL if the combined flags cannot be
* supported due to imcompatible buffer format, dataSpace, or other hardware
* limitations.
*/
uint32_t usage;

/**
* The maximum number of buffers the HAL device may need to have dequeued at
* the same time. The HAL device may not have more buffers in-flight from
* this stream than this value.
*/
uint32_t max_buffers;

/**
* A handle to HAL-private information for the stream. Will not be inspected
* by the framework code.
*/
void *priv;

/**
* A field that describes the contents of the buffer. The format and buffer
* dimensions define the memory layout and structure of the stream buffers,
* while dataSpace defines the meaning of the data within the buffer.
*
* For most formats, dataSpace defines the color space of the image data.
* In addition, for some formats, dataSpace indicates whether image- or
* depth-based data is requested. See system/core/include/system/graphics.h
* for details of formats and valid dataSpace values for each format.
*
* Version information:
*
* < CAMERA_DEVICE_API_VERSION_3_3:
*
* Not defined and should not be accessed. dataSpace should be assumed to
* be HAL_DATASPACE_UNKNOWN, and the appropriate color space, etc, should
* be determined from the usage flags and the format.
*
* = CAMERA_DEVICE_API_VERSION_3_3:
*
* Always set by the camera service. HAL must use this dataSpace to
* configure the stream to the correct colorspace, or to select between
* color and depth outputs if supported. The dataspace values are the
* legacy definitions in graphics.h
*
* >= CAMERA_DEVICE_API_VERSION_3_4:
*
* Always set by the camera service. HAL must use this dataSpace to
* configure the stream to the correct colorspace, or to select between
* color and depth outputs if supported. The dataspace values are set
* using the V0 dataspace definitions in graphics.h
*/
android_dataspace_t data_space;

/**
* The required output rotation of the stream, one of
* the camera3_stream_rotation_t values. This must be inspected by HAL along
* with stream width and height. For example, if the rotation is 90 degree
* and the stream width and height is 720 and 1280 respectively, camera service
* will supply buffers of size 720x1280, and HAL should capture a 1280x720 image
* and rotate the image by 90 degree counterclockwise. The rotation field is
* no-op when the stream type is input. Camera HAL must ignore the rotation
* field for an input stream.
*
* <= CAMERA_DEVICE_API_VERSION_3_2:
*
* Not defined and must not be accessed. HAL must not apply any rotation
* on output images.
*
* >= CAMERA_DEVICE_API_VERSION_3_3:
*
* Always set by camera service. HAL must inspect this field during stream
* configuration and returns -EINVAL if HAL cannot perform such rotation.
* HAL must always support CAMERA3_STREAM_ROTATION_0, so a
* configure_streams() call must not fail for unsupported rotation if
* rotation field of all streams is CAMERA3_STREAM_ROTATION_0.
*
*/
int rotation;

/**
* The physical camera id this stream belongs to.
*
* <= CAMERA_DEVICE_API_VERISON_3_4:
*
* Not defined and must not be accessed.
*
* >= CAMERA_DEVICE_API_VERISON_3_5:
*
* Always set by camera service. If the camera device is not a logical
* multi camera, or if the camera is a logical multi camera but the stream
* is not a physical output stream, this field will point to a 0-length
* string.
*
* A logical multi camera is a camera device backed by multiple physical
* cameras that are also exposed to the application. And for a logical
* multi camera, a physical output stream is an output stream specifically
* requested on an underlying physical camera.
*
* For an input stream, this field is guaranteed to be a 0-length string.
*/
const char* physical_camera_id;

/* reserved for future use */
void *reserved[6];

} camera3_stream_t;

该结构体主要用来代表具体的数据流实体,在整个的配置过程中,需要在上层进行填充,当下发到HAL中后,HAL会针对其中的各项属性进行配置,这里便简单介绍下其内部的各个元素的意义:

  • stream_type: 表示数据流的类型,类型在camera3_stream_type_t中被定义。
  • width: 表示当前数据流中的buffer的宽度。
  • height: 表示当前数据流中buffer的高度。
  • format: 表示当前数据流中buffer的格式,该格式是在system/core/include/system/graphics.h中被定义。
  • usage: 表示当前数据流的gralloc用法,其用法定义在gralloc.h中。
  • max_buffers: 指定了当前数据流中可能支持的最大数据buffer数量。
  • data_space: 指定了当前数据流buffer中存储的图像数据的颜色空间。
  • rotation:指定了当前数据流的输出buffer的旋转角度,其角度的定义在camera3_stream_rotation_t中,该参数由Camera Service进行设置,必须在HAL中进行设置,该参数对于input stream并没有效果。
  • physical_camera_id: 指定了当前数据流从属的物理camera Id。

4.7 camera3_stream_buffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* camera3_stream_buffer_t:
*
* A single buffer from a camera3 stream. It includes a handle to its parent
* stream, the handle to the gralloc buffer itself, and sync fences
*
* The buffer does not specify whether it is to be used for input or output;
* that is determined by its parent stream type and how the buffer is passed to
* the HAL device.
*/
typedef struct camera3_stream_buffer {
/**
* The handle of the stream this buffer is associated with
*/
camera3_stream_t *stream;

/**
* The native handle to the buffer
*/
buffer_handle_t *buffer;

/**
* Current state of the buffer, one of the camera3_buffer_status_t
* values. The framework will not pass buffers to the HAL that are in an
* error state. In case a buffer could not be filled by the HAL, it must
* have its status set to CAMERA3_BUFFER_STATUS_ERROR when returned to the
* framework with process_capture_result().
*/
int status;

/**
* The acquire sync fence for this buffer. The HAL must wait on this fence
* fd before attempting to read from or write to this buffer.
*
* The framework may be set to -1 to indicate that no waiting is necessary
* for this buffer.
*
* When the HAL returns an output buffer to the framework with
* process_capture_result(), the acquire_fence must be set to -1. If the HAL
* never waits on the acquire_fence due to an error in filling a buffer,
* when calling process_capture_result() the HAL must set the release_fence
* of the buffer to be the acquire_fence passed to it by the framework. This
* will allow the framework to wait on the fence before reusing the buffer.
*
* For input buffers, the HAL must not change the acquire_fence field during
* the process_capture_request() call.
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* When the HAL returns an input buffer to the framework with
* process_capture_result(), the acquire_fence must be set to -1. If the HAL
* never waits on input buffer acquire fence due to an error, the sync
* fences should be handled similarly to the way they are handled for output
* buffers.
*/
int acquire_fence;

/**
* The release sync fence for this buffer. The HAL must set this fence when
* returning buffers to the framework, or write -1 to indicate that no
* waiting is required for this buffer.
*
* For the output buffers, the fences must be set in the output_buffers
* array passed to process_capture_result().
*
* <= CAMERA_DEVICE_API_VERSION_3_1:
*
* For the input buffer, the release fence must be set by the
* process_capture_request() call.
*
* >= CAMERA_DEVICE_API_VERSION_3_2:
*
* For the input buffer, the fences must be set in the input_buffer
* passed to process_capture_result().
*
* After signaling the release_fence for this buffer, the HAL
* should not make any further attempts to access this buffer as the
* ownership has been fully transferred back to the framework.
*
* If a fence of -1 was specified then the ownership of this buffer
* is transferred back immediately upon the call of process_capture_result.
*/
int release_fence;

} camera3_stream_buffer_t;

该结构体主要用来代表具体的buffer对象,其中重要元素如下:

  • stream: 代表了从属的数据流
  • buffer:buffer句柄

五、总结

谷歌为了将系统框架和平台厂商的自定义部分相分离,在Android上推出了Treble项目,该项目直接将平台厂商的实现部分放入vendor分区中进行管理,进而与system分区保持隔离,这样便可以在相互独立的空间中进行各自的迭代升级,而互不干扰,而在相机框架体系中,便将Camera HAL Module从Camera Service中解耦出来,放入独立进程Camera Provider中进行管理,而为了更好的进行跨进程访问,谷歌针对Provider提出了HIDL机制用于Camera Servic对于Camera Provier的访问,而HIDL接口的实现是在Camera Provider中实现,针对Camera HAL Module的控制又是通过谷歌制定的Camera HAL3接口来完成,所以由此看来,Provider的职责也比较简单,通过HIDL机制保持与Camera Service的通信,通过HAL3接口控制着Camera HAL Module。